mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 03:38:29 +00:00
Auto merge of #107386 - flip1995:clippyup, r=Manishearth
Update Clippy r? `@Manishearth`
This commit is contained in:
commit
7d4df2d30e
@ -724,7 +724,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clippy"
|
name = "clippy"
|
||||||
version = "0.1.68"
|
version = "0.1.69"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clippy_lints",
|
"clippy_lints",
|
||||||
"clippy_utils",
|
"clippy_utils",
|
||||||
@ -766,7 +766,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clippy_lints"
|
name = "clippy_lints"
|
||||||
version = "0.1.68"
|
version = "0.1.69"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cargo_metadata 0.14.0",
|
"cargo_metadata 0.14.0",
|
||||||
"clippy_utils",
|
"clippy_utils",
|
||||||
@ -789,7 +789,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clippy_utils"
|
name = "clippy_utils"
|
||||||
version = "0.1.68"
|
version = "0.1.69"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"if_chain",
|
"if_chain",
|
||||||
@ -1168,7 +1168,7 @@ checksum = "a0afaad2b26fa326569eb264b1363e8ae3357618c43982b3f285f0774ce76b69"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "declare_clippy_lint"
|
name = "declare_clippy_lint"
|
||||||
version = "0.1.68"
|
version = "0.1.69"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itertools",
|
"itertools",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -157,6 +157,11 @@ jobs:
|
|||||||
- name: Test metadata collection
|
- name: Test metadata collection
|
||||||
run: cargo collect-metadata
|
run: cargo collect-metadata
|
||||||
|
|
||||||
|
- name: Test lint_configuration.md is up-to-date
|
||||||
|
run: |
|
||||||
|
echo "run \`cargo collect-metadata\` if this fails"
|
||||||
|
git update-index --refresh
|
||||||
|
|
||||||
integration_build:
|
integration_build:
|
||||||
needs: changelog
|
needs: changelog
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
@ -6,11 +6,204 @@ document.
|
|||||||
|
|
||||||
## Unreleased / Beta / In Rust Nightly
|
## Unreleased / Beta / In Rust Nightly
|
||||||
|
|
||||||
[4f142aa1...master](https://github.com/rust-lang/rust-clippy/compare/4f142aa1...master)
|
[d822110d...master](https://github.com/rust-lang/rust-clippy/compare/d822110d...master)
|
||||||
|
|
||||||
|
## Rust 1.67
|
||||||
|
|
||||||
|
Current stable, released 2023-01-26
|
||||||
|
|
||||||
|
[4f142aa1...d822110d](https://github.com/rust-lang/rust-clippy/compare/4f142aa1...d822110d)
|
||||||
|
|
||||||
|
### New Lints
|
||||||
|
|
||||||
|
* [`seek_from_current`]
|
||||||
|
[#9681](https://github.com/rust-lang/rust-clippy/pull/9681)
|
||||||
|
* [`from_raw_with_void_ptr`]
|
||||||
|
[#9690](https://github.com/rust-lang/rust-clippy/pull/9690)
|
||||||
|
* [`misnamed_getters`]
|
||||||
|
[#9770](https://github.com/rust-lang/rust-clippy/pull/9770)
|
||||||
|
* [`seek_to_start_instead_of_rewind`]
|
||||||
|
[#9667](https://github.com/rust-lang/rust-clippy/pull/9667)
|
||||||
|
* [`suspicious_xor_used_as_pow`]
|
||||||
|
[#9506](https://github.com/rust-lang/rust-clippy/pull/9506)
|
||||||
|
* [`unnecessary_safety_doc`]
|
||||||
|
[#9822](https://github.com/rust-lang/rust-clippy/pull/9822)
|
||||||
|
* [`unchecked_duration_subtraction`]
|
||||||
|
[#9570](https://github.com/rust-lang/rust-clippy/pull/9570)
|
||||||
|
* [`manual_is_ascii_check`]
|
||||||
|
[#9765](https://github.com/rust-lang/rust-clippy/pull/9765)
|
||||||
|
* [`unnecessary_safety_comment`]
|
||||||
|
[#9851](https://github.com/rust-lang/rust-clippy/pull/9851)
|
||||||
|
* [`let_underscore_future`]
|
||||||
|
[#9760](https://github.com/rust-lang/rust-clippy/pull/9760)
|
||||||
|
* [`manual_let_else`]
|
||||||
|
[#8437](https://github.com/rust-lang/rust-clippy/pull/8437)
|
||||||
|
|
||||||
|
### Moves and Deprecations
|
||||||
|
|
||||||
|
* Moved [`uninlined_format_args`] to `style` (Now warn-by-default)
|
||||||
|
[#9865](https://github.com/rust-lang/rust-clippy/pull/9865)
|
||||||
|
* Moved [`needless_collect`] to `nursery` (Now allow-by-default)
|
||||||
|
[#9705](https://github.com/rust-lang/rust-clippy/pull/9705)
|
||||||
|
* Moved [`or_fun_call`] to `nursery` (Now allow-by-default)
|
||||||
|
[#9829](https://github.com/rust-lang/rust-clippy/pull/9829)
|
||||||
|
* Uplifted [`let_underscore_lock`] into rustc
|
||||||
|
[#9697](https://github.com/rust-lang/rust-clippy/pull/9697)
|
||||||
|
* Uplifted [`let_underscore_drop`] into rustc
|
||||||
|
[#9697](https://github.com/rust-lang/rust-clippy/pull/9697)
|
||||||
|
* Moved [`bool_to_int_with_if`] to `pedantic` (Now allow-by-default)
|
||||||
|
[#9830](https://github.com/rust-lang/rust-clippy/pull/9830)
|
||||||
|
* Move `index_refutable_slice` to `pedantic` (Now warn-by-default)
|
||||||
|
[#9975](https://github.com/rust-lang/rust-clippy/pull/9975)
|
||||||
|
* Moved [`manual_clamp`] to `nursery` (Now allow-by-default)
|
||||||
|
[#10101](https://github.com/rust-lang/rust-clippy/pull/10101)
|
||||||
|
|
||||||
|
### Enhancements
|
||||||
|
|
||||||
|
* The scope of `#![clippy::msrv]` is now tracked correctly
|
||||||
|
[#9924](https://github.com/rust-lang/rust-clippy/pull/9924)
|
||||||
|
* `#[clippy::msrv]` can now be used as an outer attribute
|
||||||
|
[#9860](https://github.com/rust-lang/rust-clippy/pull/9860)
|
||||||
|
* Clippy will now avoid Cargo's cache, if `Cargo.toml` or `clippy.toml` have changed
|
||||||
|
[#9707](https://github.com/rust-lang/rust-clippy/pull/9707)
|
||||||
|
* [`uninlined_format_args`]: Added a new config `allow-mixed-uninlined-format-args` to allow the
|
||||||
|
lint, if only some arguments can be inlined
|
||||||
|
[#9865](https://github.com/rust-lang/rust-clippy/pull/9865)
|
||||||
|
* [`needless_lifetimes`]: Now provides suggests for individual lifetimes
|
||||||
|
[#9743](https://github.com/rust-lang/rust-clippy/pull/9743)
|
||||||
|
* [`needless_collect`]: Now detects needless `is_empty` and `contains` calls
|
||||||
|
[#8744](https://github.com/rust-lang/rust-clippy/pull/8744)
|
||||||
|
* [`blanket_clippy_restriction_lints`]: Now lints, if `clippy::restriction` is enabled via the
|
||||||
|
command line arguments
|
||||||
|
[#9755](https://github.com/rust-lang/rust-clippy/pull/9755)
|
||||||
|
* [`mutable_key_type`]: Now has the `ignore-interior-mutability` configuration, to add types which
|
||||||
|
should be ignored by the lint
|
||||||
|
[#9692](https://github.com/rust-lang/rust-clippy/pull/9692)
|
||||||
|
* [`uninlined_format_args`]: Now works for multiline `format!` expressions
|
||||||
|
[#9945](https://github.com/rust-lang/rust-clippy/pull/9945)
|
||||||
|
* [`cognitive_complexity`]: Now works for async functions
|
||||||
|
[#9828](https://github.com/rust-lang/rust-clippy/pull/9828)
|
||||||
|
[#9836](https://github.com/rust-lang/rust-clippy/pull/9836)
|
||||||
|
* [`vec_box`]: Now avoids an off-by-one error when using the `vec-box-size-threshold` configuration
|
||||||
|
[#9848](https://github.com/rust-lang/rust-clippy/pull/9848)
|
||||||
|
* [`never_loop`]: Now correctly handles breaks in nested labeled blocks
|
||||||
|
[#9858](https://github.com/rust-lang/rust-clippy/pull/9858)
|
||||||
|
[#9837](https://github.com/rust-lang/rust-clippy/pull/9837)
|
||||||
|
* [`disallowed_methods`], [`disallowed_types`], [`disallowed_macros`]: Now correctly resolve
|
||||||
|
paths, if a crate is used multiple times with different versions
|
||||||
|
[#9800](https://github.com/rust-lang/rust-clippy/pull/9800)
|
||||||
|
* [`disallowed_methods`]: Can now be used for local methods
|
||||||
|
[#9800](https://github.com/rust-lang/rust-clippy/pull/9800)
|
||||||
|
* [`print_stdout`], [`print_stderr`]: Can now be enabled in test with the `allow-print-in-tests`
|
||||||
|
config value
|
||||||
|
[#9797](https://github.com/rust-lang/rust-clippy/pull/9797)
|
||||||
|
* [`from_raw_with_void_ptr`]: Now works for `Rc`, `Arc`, `alloc::rc::Weak` and
|
||||||
|
`alloc::sync::Weak` types.
|
||||||
|
[#9700](https://github.com/rust-lang/rust-clippy/pull/9700)
|
||||||
|
* [`needless_borrowed_reference`]: Now works for struct and tuple patterns with wildcards
|
||||||
|
[#9855](https://github.com/rust-lang/rust-clippy/pull/9855)
|
||||||
|
* [`or_fun_call`]: Now supports `map_or` methods
|
||||||
|
[#9689](https://github.com/rust-lang/rust-clippy/pull/9689)
|
||||||
|
* [`unwrap_used`], [`expect_used`]: No longer lints in test code
|
||||||
|
[#9686](https://github.com/rust-lang/rust-clippy/pull/9686)
|
||||||
|
* [`fn_params_excessive_bools`]: Is now emitted with the lint level at the linted function
|
||||||
|
[#9698](https://github.com/rust-lang/rust-clippy/pull/9698)
|
||||||
|
|
||||||
|
### False Positive Fixes
|
||||||
|
|
||||||
|
* [`new_ret_no_self`]: No longer lints when `impl Trait<Self>` is returned
|
||||||
|
[#9733](https://github.com/rust-lang/rust-clippy/pull/9733)
|
||||||
|
* [`unnecessary_lazy_evaluations`]: No longer lints, if the type has a significant drop
|
||||||
|
[#9750](https://github.com/rust-lang/rust-clippy/pull/9750)
|
||||||
|
* [`option_if_let_else`]: No longer lints, if any arm has guard
|
||||||
|
[#9747](https://github.com/rust-lang/rust-clippy/pull/9747)
|
||||||
|
* [`explicit_auto_deref`]: No longer lints, if the target type is a projection with generic
|
||||||
|
arguments
|
||||||
|
[#9813](https://github.com/rust-lang/rust-clippy/pull/9813)
|
||||||
|
* [`unnecessary_to_owned`]: No longer lints, if the suggestion effects types
|
||||||
|
[#9796](https://github.com/rust-lang/rust-clippy/pull/9796)
|
||||||
|
* [`needless_borrow`]: No longer lints, if the suggestion is affected by `Deref`
|
||||||
|
[#9674](https://github.com/rust-lang/rust-clippy/pull/9674)
|
||||||
|
* [`unused_unit`]: No longer lints, if lifetimes are bound to the return type
|
||||||
|
[#9849](https://github.com/rust-lang/rust-clippy/pull/9849)
|
||||||
|
* [`mut_mut`]: No longer lints cases with unsized mutable references
|
||||||
|
[#9835](https://github.com/rust-lang/rust-clippy/pull/9835)
|
||||||
|
* [`bool_to_int_with_if`]: No longer lints in const context
|
||||||
|
[#9738](https://github.com/rust-lang/rust-clippy/pull/9738)
|
||||||
|
* [`use_self`]: No longer lints in macros
|
||||||
|
[#9704](https://github.com/rust-lang/rust-clippy/pull/9704)
|
||||||
|
* [`unnecessary_operation`]: No longer lints, if multiple macros are involved
|
||||||
|
[#9981](https://github.com/rust-lang/rust-clippy/pull/9981)
|
||||||
|
* [`allow_attributes_without_reason`]: No longer lints inside external macros
|
||||||
|
[#9630](https://github.com/rust-lang/rust-clippy/pull/9630)
|
||||||
|
* [`question_mark`]: No longer lints for `if let Err()` with an `else` branch
|
||||||
|
[#9722](https://github.com/rust-lang/rust-clippy/pull/9722)
|
||||||
|
* [`unnecessary_cast`]: No longer lints if the identifier and cast originate from different macros
|
||||||
|
[#9980](https://github.com/rust-lang/rust-clippy/pull/9980)
|
||||||
|
* [`arithmetic_side_effects`]: Now detects operations with associated constants
|
||||||
|
[#9592](https://github.com/rust-lang/rust-clippy/pull/9592)
|
||||||
|
* [`explicit_auto_deref`]: No longer lints, if the initial value is not a reference or reference
|
||||||
|
receiver
|
||||||
|
[#9997](https://github.com/rust-lang/rust-clippy/pull/9997)
|
||||||
|
* [`module_name_repetitions`], [`single_component_path_imports`]: Now handle `#[allow]`
|
||||||
|
attributes correctly
|
||||||
|
[#9879](https://github.com/rust-lang/rust-clippy/pull/9879)
|
||||||
|
* [`bool_to_int_with_if`]: No longer lints `if let` statements
|
||||||
|
[#9714](https://github.com/rust-lang/rust-clippy/pull/9714)
|
||||||
|
* [`needless_borrow`]: No longer lints, `if`-`else`-statements that require the borrow
|
||||||
|
[#9791](https://github.com/rust-lang/rust-clippy/pull/9791)
|
||||||
|
* [`needless_borrow`]: No longer lints borrows, if moves were illegal
|
||||||
|
[#9711](https://github.com/rust-lang/rust-clippy/pull/9711)
|
||||||
|
* [`manual_swap`]: No longer lints in const context
|
||||||
|
[#9871](https://github.com/rust-lang/rust-clippy/pull/9871)
|
||||||
|
|
||||||
|
### Suggestion Fixes/Improvements
|
||||||
|
|
||||||
|
* [`missing_safety_doc`], [`missing_errors_doc`], [`missing_panics_doc`]: No longer show the
|
||||||
|
entire item in the lint emission.
|
||||||
|
[#9772](https://github.com/rust-lang/rust-clippy/pull/9772)
|
||||||
|
* [`needless_lifetimes`]: Only suggests `'_` when it's applicable
|
||||||
|
[#9743](https://github.com/rust-lang/rust-clippy/pull/9743)
|
||||||
|
* [`use_self`]: Now suggests full paths correctly
|
||||||
|
[#9726](https://github.com/rust-lang/rust-clippy/pull/9726)
|
||||||
|
* [`redundant_closure_call`]: Now correctly deals with macros during suggestion creation
|
||||||
|
[#9987](https://github.com/rust-lang/rust-clippy/pull/9987)
|
||||||
|
* [`unnecessary_cast`]: Suggestions now correctly deal with references
|
||||||
|
[#9996](https://github.com/rust-lang/rust-clippy/pull/9996)
|
||||||
|
* [`unnecessary_join`]: Suggestions now correctly use [turbofish] operators
|
||||||
|
[#9779](https://github.com/rust-lang/rust-clippy/pull/9779)
|
||||||
|
* [`equatable_if_let`]: Can now suggest `matches!` replacements
|
||||||
|
[#9368](https://github.com/rust-lang/rust-clippy/pull/9368)
|
||||||
|
* [`string_extend_chars`]: Suggestions now correctly work for `str` slices
|
||||||
|
[#9741](https://github.com/rust-lang/rust-clippy/pull/9741)
|
||||||
|
* [`redundant_closure_for_method_calls`]: Suggestions now include angle brackets and generic
|
||||||
|
arguments if needed
|
||||||
|
[#9745](https://github.com/rust-lang/rust-clippy/pull/9745)
|
||||||
|
* [`manual_let_else`]: Suggestions no longer expand macro calls
|
||||||
|
[#9943](https://github.com/rust-lang/rust-clippy/pull/9943)
|
||||||
|
* [`infallible_destructuring_match`]: Suggestions now preserve references
|
||||||
|
[#9850](https://github.com/rust-lang/rust-clippy/pull/9850)
|
||||||
|
* [`result_large_err`]: The error now shows the largest enum variant
|
||||||
|
[#9662](https://github.com/rust-lang/rust-clippy/pull/9662)
|
||||||
|
* [`needless_return`]: Suggestions are now formatted better
|
||||||
|
[#9967](https://github.com/rust-lang/rust-clippy/pull/9967)
|
||||||
|
* [`unused_rounding`]: The suggestion now preserves the original float literal notation
|
||||||
|
[#9870](https://github.com/rust-lang/rust-clippy/pull/9870)
|
||||||
|
|
||||||
|
[turbofish]: https://turbo.fish/::%3CClippy%3E
|
||||||
|
|
||||||
|
### ICE Fixes
|
||||||
|
|
||||||
|
* [`result_large_err`]: Fixed ICE for empty enums
|
||||||
|
[#10007](https://github.com/rust-lang/rust-clippy/pull/10007)
|
||||||
|
* [`redundant_allocation`]: Fixed ICE for types with bounded variables
|
||||||
|
[#9773](https://github.com/rust-lang/rust-clippy/pull/9773)
|
||||||
|
* [`unused_rounding`]: Fixed ICE, if `_` was used as a separator
|
||||||
|
[#10001](https://github.com/rust-lang/rust-clippy/pull/10001)
|
||||||
|
|
||||||
## Rust 1.66
|
## Rust 1.66
|
||||||
|
|
||||||
Current stable, released 2022-12-15
|
Released 2022-12-15
|
||||||
|
|
||||||
[b52fb523...4f142aa1](https://github.com/rust-lang/rust-clippy/compare/b52fb523...4f142aa1)
|
[b52fb523...4f142aa1](https://github.com/rust-lang/rust-clippy/compare/b52fb523...4f142aa1)
|
||||||
|
|
||||||
@ -166,6 +359,7 @@ Current stable, released 2022-12-15
|
|||||||
|
|
||||||
* [`unnecessary_to_owned`]: Avoid ICEs in favor of false negatives if information is missing
|
* [`unnecessary_to_owned`]: Avoid ICEs in favor of false negatives if information is missing
|
||||||
[#9505](https://github.com/rust-lang/rust-clippy/pull/9505)
|
[#9505](https://github.com/rust-lang/rust-clippy/pull/9505)
|
||||||
|
[#10027](https://github.com/rust-lang/rust-clippy/pull/10027)
|
||||||
* [`manual_range_contains`]: No longer ICEs on values behind references
|
* [`manual_range_contains`]: No longer ICEs on values behind references
|
||||||
[#9627](https://github.com/rust-lang/rust-clippy/pull/9627)
|
[#9627](https://github.com/rust-lang/rust-clippy/pull/9627)
|
||||||
* [`needless_pass_by_value`]: No longer ICEs on unsized `dyn Fn` arguments
|
* [`needless_pass_by_value`]: No longer ICEs on unsized `dyn Fn` arguments
|
||||||
@ -4383,6 +4577,7 @@ Released 2018-09-13
|
|||||||
[`multi_assignments`]: https://rust-lang.github.io/rust-clippy/master/index.html#multi_assignments
|
[`multi_assignments`]: https://rust-lang.github.io/rust-clippy/master/index.html#multi_assignments
|
||||||
[`multiple_crate_versions`]: https://rust-lang.github.io/rust-clippy/master/index.html#multiple_crate_versions
|
[`multiple_crate_versions`]: https://rust-lang.github.io/rust-clippy/master/index.html#multiple_crate_versions
|
||||||
[`multiple_inherent_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#multiple_inherent_impl
|
[`multiple_inherent_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#multiple_inherent_impl
|
||||||
|
[`multiple_unsafe_ops_per_block`]: https://rust-lang.github.io/rust-clippy/master/index.html#multiple_unsafe_ops_per_block
|
||||||
[`must_use_candidate`]: https://rust-lang.github.io/rust-clippy/master/index.html#must_use_candidate
|
[`must_use_candidate`]: https://rust-lang.github.io/rust-clippy/master/index.html#must_use_candidate
|
||||||
[`must_use_unit`]: https://rust-lang.github.io/rust-clippy/master/index.html#must_use_unit
|
[`must_use_unit`]: https://rust-lang.github.io/rust-clippy/master/index.html#must_use_unit
|
||||||
[`mut_from_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#mut_from_ref
|
[`mut_from_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#mut_from_ref
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "clippy"
|
name = "clippy"
|
||||||
version = "0.1.68"
|
version = "0.1.69"
|
||||||
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
||||||
repository = "https://github.com/rust-lang/rust-clippy"
|
repository = "https://github.com/rust-lang/rust-clippy"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
@ -194,11 +194,21 @@ value` mapping e.g.
|
|||||||
```toml
|
```toml
|
||||||
avoid-breaking-exported-api = false
|
avoid-breaking-exported-api = false
|
||||||
disallowed-names = ["toto", "tata", "titi"]
|
disallowed-names = ["toto", "tata", "titi"]
|
||||||
cognitive-complexity-threshold = 30
|
|
||||||
```
|
```
|
||||||
|
|
||||||
See the [list of configurable lints](https://rust-lang.github.io/rust-clippy/master/index.html#Configuration),
|
The [table of configurations](https://doc.rust-lang.org/nightly/clippy/lint_configuration.html)
|
||||||
the lint descriptions contain the names and meanings of these configuration variables.
|
contains all config values, their default, and a list of lints they affect.
|
||||||
|
Each [configurable lint](https://rust-lang.github.io/rust-clippy/master/index.html#Configuration)
|
||||||
|
, also contains information about these values.
|
||||||
|
|
||||||
|
For configurations that are a list type with default values such as
|
||||||
|
[disallowed-names](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_names),
|
||||||
|
you can use the unique value `".."` to extend the default values instead of replacing them.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# default of disallowed-names is ["foo", "baz", "quux"]
|
||||||
|
disallowed-names = ["bar", ".."] # -> ["bar", "foo", "baz", "quux"]
|
||||||
|
```
|
||||||
|
|
||||||
> **Note**
|
> **Note**
|
||||||
>
|
>
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
- [Installation](installation.md)
|
- [Installation](installation.md)
|
||||||
- [Usage](usage.md)
|
- [Usage](usage.md)
|
||||||
- [Configuration](configuration.md)
|
- [Configuration](configuration.md)
|
||||||
|
- [Lint Configuration](lint_configuration.md)
|
||||||
- [Clippy's Lints](lints.md)
|
- [Clippy's Lints](lints.md)
|
||||||
- [Continuous Integration](continuous_integration/README.md)
|
- [Continuous Integration](continuous_integration/README.md)
|
||||||
- [GitHub Actions](continuous_integration/github_actions.md)
|
- [GitHub Actions](continuous_integration/github_actions.md)
|
||||||
|
@ -8,11 +8,21 @@ basic `variable = value` mapping eg.
|
|||||||
```toml
|
```toml
|
||||||
avoid-breaking-exported-api = false
|
avoid-breaking-exported-api = false
|
||||||
disallowed-names = ["toto", "tata", "titi"]
|
disallowed-names = ["toto", "tata", "titi"]
|
||||||
cognitive-complexity-threshold = 30
|
|
||||||
```
|
```
|
||||||
|
|
||||||
See the [list of configurable lints](https://rust-lang.github.io/rust-clippy/master/index.html#Configuration),
|
The [table of configurations](./lint_configuration.md)
|
||||||
the lint descriptions contain the names and meanings of these configuration variables.
|
contains all config values, their default, and a list of lints they affect.
|
||||||
|
Each [configurable lint](https://rust-lang.github.io/rust-clippy/master/index.html#Configuration)
|
||||||
|
, also contains information about these values.
|
||||||
|
|
||||||
|
For configurations that are a list type with default values such as
|
||||||
|
[disallowed-names](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_names),
|
||||||
|
you can use the unique value `".."` to extend the default values instead of replacing them.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# default of disallowed-names is ["foo", "baz", "quux"]
|
||||||
|
disallowed-names = ["bar", ".."] # -> ["bar", "foo", "baz", "quux"]
|
||||||
|
```
|
||||||
|
|
||||||
To deactivate the "for further information visit *lint-link*" message you can define the `CLIPPY_DISABLE_DOCS_LINKS`
|
To deactivate the "for further information visit *lint-link*" message you can define the `CLIPPY_DISABLE_DOCS_LINKS`
|
||||||
environment variable.
|
environment variable.
|
||||||
|
@ -146,7 +146,8 @@ For cargo lints, the process of testing differs in that we are interested in the
|
|||||||
manifest.
|
manifest.
|
||||||
|
|
||||||
If our new lint is named e.g. `foo_categories`, after running `cargo dev
|
If our new lint is named e.g. `foo_categories`, after running `cargo dev
|
||||||
new_lint` we will find by default two new crates, each with its manifest file:
|
new_lint --name=foo_categories --type=cargo --category=cargo` we will find by
|
||||||
|
default two new crates, each with its manifest file:
|
||||||
|
|
||||||
* `tests/ui-cargo/foo_categories/fail/Cargo.toml`: this file should cause the
|
* `tests/ui-cargo/foo_categories/fail/Cargo.toml`: this file should cause the
|
||||||
new lint to raise an error.
|
new lint to raise an error.
|
||||||
@ -699,6 +700,10 @@ for some users. Adding a configuration is done in the following steps:
|
|||||||
`clippy.toml` file with the configuration value and a rust file that
|
`clippy.toml` file with the configuration value and a rust file that
|
||||||
should be linted by Clippy. The test can otherwise be written as usual.
|
should be linted by Clippy. The test can otherwise be written as usual.
|
||||||
|
|
||||||
|
5. Update [Lint Configuration](../lint_configuration.md)
|
||||||
|
|
||||||
|
Run `cargo collect-metadata` to generate documentation changes for the book.
|
||||||
|
|
||||||
[`clippy_lints::utils::conf`]: https://github.com/rust-lang/rust-clippy/blob/master/clippy_lints/src/utils/conf.rs
|
[`clippy_lints::utils::conf`]: https://github.com/rust-lang/rust-clippy/blob/master/clippy_lints/src/utils/conf.rs
|
||||||
[`clippy_lints` lib file]: https://github.com/rust-lang/rust-clippy/blob/master/clippy_lints/src/lib.rs
|
[`clippy_lints` lib file]: https://github.com/rust-lang/rust-clippy/blob/master/clippy_lints/src/lib.rs
|
||||||
[`tests/ui`]: https://github.com/rust-lang/rust-clippy/blob/master/tests/ui
|
[`tests/ui`]: https://github.com/rust-lang/rust-clippy/blob/master/tests/ui
|
||||||
|
@ -3,15 +3,15 @@
|
|||||||
This document explains how to make additions and changes to the Clippy book, the
|
This document explains how to make additions and changes to the Clippy book, the
|
||||||
guide to Clippy that you're reading right now. The Clippy book is formatted with
|
guide to Clippy that you're reading right now. The Clippy book is formatted with
|
||||||
[Markdown](https://www.markdownguide.org) and generated by
|
[Markdown](https://www.markdownguide.org) and generated by
|
||||||
[mdbook](https://github.com/rust-lang/mdBook).
|
[mdBook](https://github.com/rust-lang/mdBook).
|
||||||
|
|
||||||
- [Get mdbook](#get-mdbook)
|
- [Get mdBook](#get-mdbook)
|
||||||
- [Make changes](#make-changes)
|
- [Make changes](#make-changes)
|
||||||
|
|
||||||
## Get mdbook
|
## Get mdBook
|
||||||
|
|
||||||
While not strictly necessary since the book source is simply Markdown text
|
While not strictly necessary since the book source is simply Markdown text
|
||||||
files, having mdbook locally will allow you to build, test and serve the book
|
files, having mdBook locally will allow you to build, test and serve the book
|
||||||
locally to view changes before you commit them to the repository. You likely
|
locally to view changes before you commit them to the repository. You likely
|
||||||
already have `cargo` installed, so the easiest option is to simply:
|
already have `cargo` installed, so the easiest option is to simply:
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ already have `cargo` installed, so the easiest option is to simply:
|
|||||||
cargo install mdbook
|
cargo install mdbook
|
||||||
```
|
```
|
||||||
|
|
||||||
See the mdbook [installation](https://github.com/rust-lang/mdBook#installation)
|
See the mdBook [installation](https://github.com/rust-lang/mdBook#installation)
|
||||||
instructions for other options.
|
instructions for other options.
|
||||||
|
|
||||||
## Make changes
|
## Make changes
|
||||||
@ -27,7 +27,7 @@ instructions for other options.
|
|||||||
The book's
|
The book's
|
||||||
[src](https://github.com/rust-lang/rust-clippy/tree/master/book/src)
|
[src](https://github.com/rust-lang/rust-clippy/tree/master/book/src)
|
||||||
directory contains all of the markdown files used to generate the book. If you
|
directory contains all of the markdown files used to generate the book. If you
|
||||||
want to see your changes in real time, you can use the mdbook `serve` command to
|
want to see your changes in real time, you can use the mdBook `serve` command to
|
||||||
run a web server locally that will automatically update changes as they are
|
run a web server locally that will automatically update changes as they are
|
||||||
made. From the top level of your `rust-clippy` directory:
|
made. From the top level of your `rust-clippy` directory:
|
||||||
|
|
||||||
@ -38,5 +38,5 @@ mdbook serve book --open
|
|||||||
Then navigate to `http://localhost:3000` to see the generated book. While the
|
Then navigate to `http://localhost:3000` to see the generated book. While the
|
||||||
server is running, changes you make will automatically be updated.
|
server is running, changes you make will automatically be updated.
|
||||||
|
|
||||||
For more information, see the mdbook
|
For more information, see the mdBook
|
||||||
[guide](https://rust-lang.github.io/mdBook/).
|
[guide](https://rust-lang.github.io/mdBook/).
|
||||||
|
@ -95,11 +95,23 @@ As section headers, we use:
|
|||||||
Please also be sure to update the Beta/Unreleased sections at the top with the
|
Please also be sure to update the Beta/Unreleased sections at the top with the
|
||||||
relevant commit ranges.
|
relevant commit ranges.
|
||||||
|
|
||||||
If you have the time, it would be appreciated if you double-check, that the
|
#### 3.1 Include `beta-accepted` PRs
|
||||||
`#[clippy::version]` attributes for the added lints contains the correct version.
|
|
||||||
|
Look for the [`beta-accepted`] label and make sure to also include the PRs with
|
||||||
|
that label in the changelog. If you can, remove the `beta-accepted` labels
|
||||||
|
**after** the changelog PR was merged.
|
||||||
|
|
||||||
|
> _Note:_ Some of those PRs might even got backported to the previous `beta`.
|
||||||
|
> Those have to be included in the changelog of the _previous_ release.
|
||||||
|
|
||||||
|
### 4. Update `clippy::version` attributes
|
||||||
|
|
||||||
|
Next, make sure to check that the `#[clippy::version]` attributes for the added
|
||||||
|
lints contain the correct version.
|
||||||
|
|
||||||
[changelog]: https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md
|
[changelog]: https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md
|
||||||
[forge]: https://forge.rust-lang.org/
|
[forge]: https://forge.rust-lang.org/
|
||||||
[rust_master_tools]: https://github.com/rust-lang/rust/tree/master/src/tools/clippy
|
[rust_master_tools]: https://github.com/rust-lang/rust/tree/master/src/tools/clippy
|
||||||
[rust_beta_tools]: https://github.com/rust-lang/rust/tree/beta/src/tools/clippy
|
[rust_beta_tools]: https://github.com/rust-lang/rust/tree/beta/src/tools/clippy
|
||||||
[rust_stable_tools]: https://github.com/rust-lang/rust/releases
|
[rust_stable_tools]: https://github.com/rust-lang/rust/releases
|
||||||
|
[`beta-accepted`]: https://github.com/rust-lang/rust-clippy/issues?q=label%3Abeta-accepted+
|
||||||
|
523
src/tools/clippy/book/src/lint_configuration.md
Normal file
523
src/tools/clippy/book/src/lint_configuration.md
Normal file
@ -0,0 +1,523 @@
|
|||||||
|
<!--
|
||||||
|
This file is generated by `cargo collect-metadata`.
|
||||||
|
Please use that command to update the file and do not edit it by hand.
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Lint Configuration Options
|
||||||
|
| <div style="width:290px">Option</div> | Default Value |
|
||||||
|
|--|--|
|
||||||
|
| [arithmetic-side-effects-allowed](#arithmetic-side-effects-allowed) | `{}` |
|
||||||
|
| [arithmetic-side-effects-allowed-binary](#arithmetic-side-effects-allowed-binary) | `[]` |
|
||||||
|
| [arithmetic-side-effects-allowed-unary](#arithmetic-side-effects-allowed-unary) | `{}` |
|
||||||
|
| [avoid-breaking-exported-api](#avoid-breaking-exported-api) | `true` |
|
||||||
|
| [msrv](#msrv) | `None` |
|
||||||
|
| [cognitive-complexity-threshold](#cognitive-complexity-threshold) | `25` |
|
||||||
|
| [disallowed-names](#disallowed-names) | `["foo", "baz", "quux"]` |
|
||||||
|
| [doc-valid-idents](#doc-valid-idents) | `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenDNS", "WebGL", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]` |
|
||||||
|
| [too-many-arguments-threshold](#too-many-arguments-threshold) | `7` |
|
||||||
|
| [type-complexity-threshold](#type-complexity-threshold) | `250` |
|
||||||
|
| [single-char-binding-names-threshold](#single-char-binding-names-threshold) | `4` |
|
||||||
|
| [too-large-for-stack](#too-large-for-stack) | `200` |
|
||||||
|
| [enum-variant-name-threshold](#enum-variant-name-threshold) | `3` |
|
||||||
|
| [enum-variant-size-threshold](#enum-variant-size-threshold) | `200` |
|
||||||
|
| [verbose-bit-mask-threshold](#verbose-bit-mask-threshold) | `1` |
|
||||||
|
| [literal-representation-threshold](#literal-representation-threshold) | `16384` |
|
||||||
|
| [trivial-copy-size-limit](#trivial-copy-size-limit) | `None` |
|
||||||
|
| [pass-by-value-size-limit](#pass-by-value-size-limit) | `256` |
|
||||||
|
| [too-many-lines-threshold](#too-many-lines-threshold) | `100` |
|
||||||
|
| [array-size-threshold](#array-size-threshold) | `512000` |
|
||||||
|
| [vec-box-size-threshold](#vec-box-size-threshold) | `4096` |
|
||||||
|
| [max-trait-bounds](#max-trait-bounds) | `3` |
|
||||||
|
| [max-struct-bools](#max-struct-bools) | `3` |
|
||||||
|
| [max-fn-params-bools](#max-fn-params-bools) | `3` |
|
||||||
|
| [warn-on-all-wildcard-imports](#warn-on-all-wildcard-imports) | `false` |
|
||||||
|
| [disallowed-macros](#disallowed-macros) | `[]` |
|
||||||
|
| [disallowed-methods](#disallowed-methods) | `[]` |
|
||||||
|
| [disallowed-types](#disallowed-types) | `[]` |
|
||||||
|
| [unreadable-literal-lint-fractions](#unreadable-literal-lint-fractions) | `true` |
|
||||||
|
| [upper-case-acronyms-aggressive](#upper-case-acronyms-aggressive) | `false` |
|
||||||
|
| [matches-for-let-else](#matches-for-let-else) | `WellKnownTypes` |
|
||||||
|
| [cargo-ignore-publish](#cargo-ignore-publish) | `false` |
|
||||||
|
| [standard-macro-braces](#standard-macro-braces) | `[]` |
|
||||||
|
| [enforced-import-renames](#enforced-import-renames) | `[]` |
|
||||||
|
| [allowed-scripts](#allowed-scripts) | `["Latin"]` |
|
||||||
|
| [enable-raw-pointer-heuristic-for-send](#enable-raw-pointer-heuristic-for-send) | `true` |
|
||||||
|
| [max-suggested-slice-pattern-length](#max-suggested-slice-pattern-length) | `3` |
|
||||||
|
| [max-include-file-size](#max-include-file-size) | `1000000` |
|
||||||
|
| [allow-expect-in-tests](#allow-expect-in-tests) | `false` |
|
||||||
|
| [allow-unwrap-in-tests](#allow-unwrap-in-tests) | `false` |
|
||||||
|
| [allow-dbg-in-tests](#allow-dbg-in-tests) | `false` |
|
||||||
|
| [allow-print-in-tests](#allow-print-in-tests) | `false` |
|
||||||
|
| [large-error-threshold](#large-error-threshold) | `128` |
|
||||||
|
| [ignore-interior-mutability](#ignore-interior-mutability) | `["bytes::Bytes"]` |
|
||||||
|
| [allow-mixed-uninlined-format-args](#allow-mixed-uninlined-format-args) | `true` |
|
||||||
|
| [suppress-restriction-lint-in-const](#suppress-restriction-lint-in-const) | `false` |
|
||||||
|
|
||||||
|
### arithmetic-side-effects-allowed
|
||||||
|
Suppress checking of the passed type names in all types of operations.
|
||||||
|
|
||||||
|
If a specific operation is desired, consider using `arithmetic_side_effects_allowed_binary` or `arithmetic_side_effects_allowed_unary` instead.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```toml
|
||||||
|
arithmetic-side-effects-allowed = ["SomeType", "AnotherType"]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Noteworthy
|
||||||
|
|
||||||
|
A type, say `SomeType`, listed in this configuration has the same behavior of
|
||||||
|
`["SomeType" , "*"], ["*", "SomeType"]` in `arithmetic_side_effects_allowed_binary`.
|
||||||
|
|
||||||
|
**Default Value:** `{}` (`rustc_data_structures::fx::FxHashSet<String>`)
|
||||||
|
|
||||||
|
* [arithmetic_side_effects](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects)
|
||||||
|
|
||||||
|
|
||||||
|
### arithmetic-side-effects-allowed-binary
|
||||||
|
Suppress checking of the passed type pair names in binary operations like addition or
|
||||||
|
multiplication.
|
||||||
|
|
||||||
|
Supports the "*" wildcard to indicate that a certain type won't trigger the lint regardless
|
||||||
|
of the involved counterpart. For example, `["SomeType", "*"]` or `["*", "AnotherType"]`.
|
||||||
|
|
||||||
|
Pairs are asymmetric, which means that `["SomeType", "AnotherType"]` is not the same as
|
||||||
|
`["AnotherType", "SomeType"]`.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```toml
|
||||||
|
arithmetic-side-effects-allowed-binary = [["SomeType" , "f32"], ["AnotherType", "*"]]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Default Value:** `[]` (`Vec<[String; 2]>`)
|
||||||
|
|
||||||
|
* [arithmetic_side_effects](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects)
|
||||||
|
|
||||||
|
|
||||||
|
### arithmetic-side-effects-allowed-unary
|
||||||
|
Suppress checking of the passed type names in unary operations like "negation" (`-`).
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```toml
|
||||||
|
arithmetic-side-effects-allowed-unary = ["SomeType", "AnotherType"]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Default Value:** `{}` (`rustc_data_structures::fx::FxHashSet<String>`)
|
||||||
|
|
||||||
|
* [arithmetic_side_effects](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects)
|
||||||
|
|
||||||
|
|
||||||
|
### avoid-breaking-exported-api
|
||||||
|
Suppress lints whenever the suggested change would cause breakage for other crates.
|
||||||
|
|
||||||
|
**Default Value:** `true` (`bool`)
|
||||||
|
|
||||||
|
* [enum_variant_names](https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names)
|
||||||
|
* [large_types_passed_by_value](https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value)
|
||||||
|
* [trivially_copy_pass_by_ref](https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref)
|
||||||
|
* [unnecessary_wraps](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_wraps)
|
||||||
|
* [unused_self](https://rust-lang.github.io/rust-clippy/master/index.html#unused_self)
|
||||||
|
* [upper_case_acronyms](https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms)
|
||||||
|
* [wrong_self_convention](https://rust-lang.github.io/rust-clippy/master/index.html#wrong_self_convention)
|
||||||
|
* [box_collection](https://rust-lang.github.io/rust-clippy/master/index.html#box_collection)
|
||||||
|
* [redundant_allocation](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation)
|
||||||
|
* [rc_buffer](https://rust-lang.github.io/rust-clippy/master/index.html#rc_buffer)
|
||||||
|
* [vec_box](https://rust-lang.github.io/rust-clippy/master/index.html#vec_box)
|
||||||
|
* [option_option](https://rust-lang.github.io/rust-clippy/master/index.html#option_option)
|
||||||
|
* [linkedlist](https://rust-lang.github.io/rust-clippy/master/index.html#linkedlist)
|
||||||
|
* [rc_mutex](https://rust-lang.github.io/rust-clippy/master/index.html#rc_mutex)
|
||||||
|
|
||||||
|
|
||||||
|
### msrv
|
||||||
|
The minimum rust version that the project supports
|
||||||
|
|
||||||
|
**Default Value:** `None` (`Option<String>`)
|
||||||
|
|
||||||
|
* [manual_split_once](https://rust-lang.github.io/rust-clippy/master/index.html#manual_split_once)
|
||||||
|
* [manual_str_repeat](https://rust-lang.github.io/rust-clippy/master/index.html#manual_str_repeat)
|
||||||
|
* [cloned_instead_of_copied](https://rust-lang.github.io/rust-clippy/master/index.html#cloned_instead_of_copied)
|
||||||
|
* [redundant_field_names](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names)
|
||||||
|
* [redundant_static_lifetimes](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes)
|
||||||
|
* [filter_map_next](https://rust-lang.github.io/rust-clippy/master/index.html#filter_map_next)
|
||||||
|
* [checked_conversions](https://rust-lang.github.io/rust-clippy/master/index.html#checked_conversions)
|
||||||
|
* [manual_range_contains](https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains)
|
||||||
|
* [use_self](https://rust-lang.github.io/rust-clippy/master/index.html#use_self)
|
||||||
|
* [mem_replace_with_default](https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_default)
|
||||||
|
* [manual_non_exhaustive](https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive)
|
||||||
|
* [option_as_ref_deref](https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref)
|
||||||
|
* [map_unwrap_or](https://rust-lang.github.io/rust-clippy/master/index.html#map_unwrap_or)
|
||||||
|
* [match_like_matches_macro](https://rust-lang.github.io/rust-clippy/master/index.html#match_like_matches_macro)
|
||||||
|
* [manual_strip](https://rust-lang.github.io/rust-clippy/master/index.html#manual_strip)
|
||||||
|
* [missing_const_for_fn](https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn)
|
||||||
|
* [unnested_or_patterns](https://rust-lang.github.io/rust-clippy/master/index.html#unnested_or_patterns)
|
||||||
|
* [from_over_into](https://rust-lang.github.io/rust-clippy/master/index.html#from_over_into)
|
||||||
|
* [ptr_as_ptr](https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr)
|
||||||
|
* [if_then_some_else_none](https://rust-lang.github.io/rust-clippy/master/index.html#if_then_some_else_none)
|
||||||
|
* [approx_constant](https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant)
|
||||||
|
* [deprecated_cfg_attr](https://rust-lang.github.io/rust-clippy/master/index.html#deprecated_cfg_attr)
|
||||||
|
* [index_refutable_slice](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice)
|
||||||
|
* [map_clone](https://rust-lang.github.io/rust-clippy/master/index.html#map_clone)
|
||||||
|
* [borrow_as_ptr](https://rust-lang.github.io/rust-clippy/master/index.html#borrow_as_ptr)
|
||||||
|
* [manual_bits](https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits)
|
||||||
|
* [err_expect](https://rust-lang.github.io/rust-clippy/master/index.html#err_expect)
|
||||||
|
* [cast_abs_to_unsigned](https://rust-lang.github.io/rust-clippy/master/index.html#cast_abs_to_unsigned)
|
||||||
|
* [uninlined_format_args](https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args)
|
||||||
|
* [manual_clamp](https://rust-lang.github.io/rust-clippy/master/index.html#manual_clamp)
|
||||||
|
* [manual_let_else](https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else)
|
||||||
|
* [unchecked_duration_subtraction](https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_duration_subtraction)
|
||||||
|
|
||||||
|
|
||||||
|
### cognitive-complexity-threshold
|
||||||
|
The maximum cognitive complexity a function can have
|
||||||
|
|
||||||
|
**Default Value:** `25` (`u64`)
|
||||||
|
|
||||||
|
* [cognitive_complexity](https://rust-lang.github.io/rust-clippy/master/index.html#cognitive_complexity)
|
||||||
|
|
||||||
|
|
||||||
|
### disallowed-names
|
||||||
|
The list of disallowed names to lint about. NB: `bar` is not here since it has legitimate uses. The value
|
||||||
|
`".."` can be used as part of the list to indicate, that the configured values should be appended to the
|
||||||
|
default configuration of Clippy. By default any configuration will replace the default value.
|
||||||
|
|
||||||
|
**Default Value:** `["foo", "baz", "quux"]` (`Vec<String>`)
|
||||||
|
|
||||||
|
* [disallowed_names](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_names)
|
||||||
|
|
||||||
|
|
||||||
|
### doc-valid-idents
|
||||||
|
The list of words this lint should not consider as identifiers needing ticks. The value
|
||||||
|
`".."` 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 configuraction will replace the default value. For example:
|
||||||
|
* `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`.
|
||||||
|
* `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", "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>`)
|
||||||
|
|
||||||
|
* [doc_markdown](https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown)
|
||||||
|
|
||||||
|
|
||||||
|
### too-many-arguments-threshold
|
||||||
|
The maximum number of argument a function or method can have
|
||||||
|
|
||||||
|
**Default Value:** `7` (`u64`)
|
||||||
|
|
||||||
|
* [too_many_arguments](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_arguments)
|
||||||
|
|
||||||
|
|
||||||
|
### type-complexity-threshold
|
||||||
|
The maximum complexity a type can have
|
||||||
|
|
||||||
|
**Default Value:** `250` (`u64`)
|
||||||
|
|
||||||
|
* [type_complexity](https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity)
|
||||||
|
|
||||||
|
|
||||||
|
### single-char-binding-names-threshold
|
||||||
|
The maximum number of single char bindings a scope may have
|
||||||
|
|
||||||
|
**Default Value:** `4` (`u64`)
|
||||||
|
|
||||||
|
* [many_single_char_names](https://rust-lang.github.io/rust-clippy/master/index.html#many_single_char_names)
|
||||||
|
|
||||||
|
|
||||||
|
### too-large-for-stack
|
||||||
|
The maximum size of objects (in bytes) that will be linted. Larger objects are ok on the heap
|
||||||
|
|
||||||
|
**Default Value:** `200` (`u64`)
|
||||||
|
|
||||||
|
* [boxed_local](https://rust-lang.github.io/rust-clippy/master/index.html#boxed_local)
|
||||||
|
* [useless_vec](https://rust-lang.github.io/rust-clippy/master/index.html#useless_vec)
|
||||||
|
|
||||||
|
|
||||||
|
### enum-variant-name-threshold
|
||||||
|
The minimum number of enum variants for the lints about variant names to trigger
|
||||||
|
|
||||||
|
**Default Value:** `3` (`u64`)
|
||||||
|
|
||||||
|
* [enum_variant_names](https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names)
|
||||||
|
|
||||||
|
|
||||||
|
### enum-variant-size-threshold
|
||||||
|
The maximum size of an enum's variant to avoid box suggestion
|
||||||
|
|
||||||
|
**Default Value:** `200` (`u64`)
|
||||||
|
|
||||||
|
* [large_enum_variant](https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant)
|
||||||
|
|
||||||
|
|
||||||
|
### verbose-bit-mask-threshold
|
||||||
|
The maximum allowed size of a bit mask before suggesting to use 'trailing_zeros'
|
||||||
|
|
||||||
|
**Default Value:** `1` (`u64`)
|
||||||
|
|
||||||
|
* [verbose_bit_mask](https://rust-lang.github.io/rust-clippy/master/index.html#verbose_bit_mask)
|
||||||
|
|
||||||
|
|
||||||
|
### literal-representation-threshold
|
||||||
|
The lower bound for linting decimal literals
|
||||||
|
|
||||||
|
**Default Value:** `16384` (`u64`)
|
||||||
|
|
||||||
|
* [decimal_literal_representation](https://rust-lang.github.io/rust-clippy/master/index.html#decimal_literal_representation)
|
||||||
|
|
||||||
|
|
||||||
|
### trivial-copy-size-limit
|
||||||
|
The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by reference.
|
||||||
|
|
||||||
|
**Default Value:** `None` (`Option<u64>`)
|
||||||
|
|
||||||
|
* [trivially_copy_pass_by_ref](https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref)
|
||||||
|
|
||||||
|
|
||||||
|
### pass-by-value-size-limit
|
||||||
|
The minimum size (in bytes) to consider a type for passing by reference instead of by value.
|
||||||
|
|
||||||
|
**Default Value:** `256` (`u64`)
|
||||||
|
|
||||||
|
* [large_type_pass_by_move](https://rust-lang.github.io/rust-clippy/master/index.html#large_type_pass_by_move)
|
||||||
|
|
||||||
|
|
||||||
|
### too-many-lines-threshold
|
||||||
|
The maximum number of lines a function or method can have
|
||||||
|
|
||||||
|
**Default Value:** `100` (`u64`)
|
||||||
|
|
||||||
|
* [too_many_lines](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines)
|
||||||
|
|
||||||
|
|
||||||
|
### array-size-threshold
|
||||||
|
The maximum allowed size for arrays on the stack
|
||||||
|
|
||||||
|
**Default Value:** `512000` (`u128`)
|
||||||
|
|
||||||
|
* [large_stack_arrays](https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays)
|
||||||
|
* [large_const_arrays](https://rust-lang.github.io/rust-clippy/master/index.html#large_const_arrays)
|
||||||
|
|
||||||
|
|
||||||
|
### vec-box-size-threshold
|
||||||
|
The size of the boxed type in bytes, where boxing in a `Vec` is allowed
|
||||||
|
|
||||||
|
**Default Value:** `4096` (`u64`)
|
||||||
|
|
||||||
|
* [vec_box](https://rust-lang.github.io/rust-clippy/master/index.html#vec_box)
|
||||||
|
|
||||||
|
|
||||||
|
### max-trait-bounds
|
||||||
|
The maximum number of bounds a trait can have to be linted
|
||||||
|
|
||||||
|
**Default Value:** `3` (`u64`)
|
||||||
|
|
||||||
|
* [type_repetition_in_bounds](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds)
|
||||||
|
|
||||||
|
|
||||||
|
### max-struct-bools
|
||||||
|
The maximum number of bool fields a struct can have
|
||||||
|
|
||||||
|
**Default Value:** `3` (`u64`)
|
||||||
|
|
||||||
|
* [struct_excessive_bools](https://rust-lang.github.io/rust-clippy/master/index.html#struct_excessive_bools)
|
||||||
|
|
||||||
|
|
||||||
|
### max-fn-params-bools
|
||||||
|
The maximum number of bool parameters a function can have
|
||||||
|
|
||||||
|
**Default Value:** `3` (`u64`)
|
||||||
|
|
||||||
|
* [fn_params_excessive_bools](https://rust-lang.github.io/rust-clippy/master/index.html#fn_params_excessive_bools)
|
||||||
|
|
||||||
|
|
||||||
|
### warn-on-all-wildcard-imports
|
||||||
|
Whether to allow certain wildcard imports (prelude, super in tests).
|
||||||
|
|
||||||
|
**Default Value:** `false` (`bool`)
|
||||||
|
|
||||||
|
* [wildcard_imports](https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_imports)
|
||||||
|
|
||||||
|
|
||||||
|
### disallowed-macros
|
||||||
|
The list of disallowed macros, written as fully qualified paths.
|
||||||
|
|
||||||
|
**Default Value:** `[]` (`Vec<crate::utils::conf::DisallowedPath>`)
|
||||||
|
|
||||||
|
* [disallowed_macros](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_macros)
|
||||||
|
|
||||||
|
|
||||||
|
### disallowed-methods
|
||||||
|
The list of disallowed methods, written as fully qualified paths.
|
||||||
|
|
||||||
|
**Default Value:** `[]` (`Vec<crate::utils::conf::DisallowedPath>`)
|
||||||
|
|
||||||
|
* [disallowed_methods](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_methods)
|
||||||
|
|
||||||
|
|
||||||
|
### disallowed-types
|
||||||
|
The list of disallowed types, written as fully qualified paths.
|
||||||
|
|
||||||
|
**Default Value:** `[]` (`Vec<crate::utils::conf::DisallowedPath>`)
|
||||||
|
|
||||||
|
* [disallowed_types](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_types)
|
||||||
|
|
||||||
|
|
||||||
|
### unreadable-literal-lint-fractions
|
||||||
|
Should the fraction of a decimal be linted to include separators.
|
||||||
|
|
||||||
|
**Default Value:** `true` (`bool`)
|
||||||
|
|
||||||
|
* [unreadable_literal](https://rust-lang.github.io/rust-clippy/master/index.html#unreadable_literal)
|
||||||
|
|
||||||
|
|
||||||
|
### upper-case-acronyms-aggressive
|
||||||
|
Enables verbose mode. Triggers if there is more than one uppercase char next to each other
|
||||||
|
|
||||||
|
**Default Value:** `false` (`bool`)
|
||||||
|
|
||||||
|
* [upper_case_acronyms](https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms)
|
||||||
|
|
||||||
|
|
||||||
|
### matches-for-let-else
|
||||||
|
Whether the matches should be considered by the lint, and whether there should
|
||||||
|
be filtering for common types.
|
||||||
|
|
||||||
|
**Default Value:** `WellKnownTypes` (`crate::manual_let_else::MatchLintBehaviour`)
|
||||||
|
|
||||||
|
* [manual_let_else](https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else)
|
||||||
|
|
||||||
|
|
||||||
|
### cargo-ignore-publish
|
||||||
|
For internal testing only, ignores the current `publish` settings in the Cargo manifest.
|
||||||
|
|
||||||
|
**Default Value:** `false` (`bool`)
|
||||||
|
|
||||||
|
* [_cargo_common_metadata](https://rust-lang.github.io/rust-clippy/master/index.html#_cargo_common_metadata)
|
||||||
|
|
||||||
|
|
||||||
|
### standard-macro-braces
|
||||||
|
Enforce the named macros always use the braces specified.
|
||||||
|
|
||||||
|
A `MacroMatcher` can be added like so `{ name = "macro_name", brace = "(" }`. If the macro
|
||||||
|
is 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.
|
||||||
|
|
||||||
|
**Default Value:** `[]` (`Vec<crate::nonstandard_macro_braces::MacroMatcher>`)
|
||||||
|
|
||||||
|
* [nonstandard_macro_braces](https://rust-lang.github.io/rust-clippy/master/index.html#nonstandard_macro_braces)
|
||||||
|
|
||||||
|
|
||||||
|
### enforced-import-renames
|
||||||
|
The list of imports to always rename, a fully qualified path followed by the rename.
|
||||||
|
|
||||||
|
**Default Value:** `[]` (`Vec<crate::utils::conf::Rename>`)
|
||||||
|
|
||||||
|
* [missing_enforced_import_renames](https://rust-lang.github.io/rust-clippy/master/index.html#missing_enforced_import_renames)
|
||||||
|
|
||||||
|
|
||||||
|
### allowed-scripts
|
||||||
|
The list of unicode scripts allowed to be used in the scope.
|
||||||
|
|
||||||
|
**Default Value:** `["Latin"]` (`Vec<String>`)
|
||||||
|
|
||||||
|
* [disallowed_script_idents](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_script_idents)
|
||||||
|
|
||||||
|
|
||||||
|
### enable-raw-pointer-heuristic-for-send
|
||||||
|
Whether to apply the raw pointer heuristic to determine if a type is `Send`.
|
||||||
|
|
||||||
|
**Default Value:** `true` (`bool`)
|
||||||
|
|
||||||
|
* [non_send_fields_in_send_ty](https://rust-lang.github.io/rust-clippy/master/index.html#non_send_fields_in_send_ty)
|
||||||
|
|
||||||
|
|
||||||
|
### max-suggested-slice-pattern-length
|
||||||
|
When Clippy suggests using a slice pattern, this is the maximum number of elements allowed in
|
||||||
|
the slice pattern that is suggested. If more elements would be necessary, the lint is suppressed.
|
||||||
|
For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements.
|
||||||
|
|
||||||
|
**Default Value:** `3` (`u64`)
|
||||||
|
|
||||||
|
* [index_refutable_slice](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice)
|
||||||
|
|
||||||
|
|
||||||
|
### max-include-file-size
|
||||||
|
The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes
|
||||||
|
|
||||||
|
**Default Value:** `1000000` (`u64`)
|
||||||
|
|
||||||
|
* [large_include_file](https://rust-lang.github.io/rust-clippy/master/index.html#large_include_file)
|
||||||
|
|
||||||
|
|
||||||
|
### allow-expect-in-tests
|
||||||
|
Whether `expect` should be allowed within `#[cfg(test)]`
|
||||||
|
|
||||||
|
**Default Value:** `false` (`bool`)
|
||||||
|
|
||||||
|
* [expect_used](https://rust-lang.github.io/rust-clippy/master/index.html#expect_used)
|
||||||
|
|
||||||
|
|
||||||
|
### allow-unwrap-in-tests
|
||||||
|
Whether `unwrap` should be allowed in test cfg
|
||||||
|
|
||||||
|
**Default Value:** `false` (`bool`)
|
||||||
|
|
||||||
|
* [unwrap_used](https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used)
|
||||||
|
|
||||||
|
|
||||||
|
### allow-dbg-in-tests
|
||||||
|
Whether `dbg!` should be allowed in test functions
|
||||||
|
|
||||||
|
**Default Value:** `false` (`bool`)
|
||||||
|
|
||||||
|
* [dbg_macro](https://rust-lang.github.io/rust-clippy/master/index.html#dbg_macro)
|
||||||
|
|
||||||
|
|
||||||
|
### allow-print-in-tests
|
||||||
|
Whether print macros (ex. `println!`) should be allowed in test functions
|
||||||
|
|
||||||
|
**Default Value:** `false` (`bool`)
|
||||||
|
|
||||||
|
* [print_stdout](https://rust-lang.github.io/rust-clippy/master/index.html#print_stdout)
|
||||||
|
* [print_stderr](https://rust-lang.github.io/rust-clippy/master/index.html#print_stderr)
|
||||||
|
|
||||||
|
|
||||||
|
### large-error-threshold
|
||||||
|
The maximum size of the `Err`-variant in a `Result` returned from a function
|
||||||
|
|
||||||
|
**Default Value:** `128` (`u64`)
|
||||||
|
|
||||||
|
* [result_large_err](https://rust-lang.github.io/rust-clippy/master/index.html#result_large_err)
|
||||||
|
|
||||||
|
|
||||||
|
### ignore-interior-mutability
|
||||||
|
A list of paths to types that should be treated like `Arc`, i.e. ignored but
|
||||||
|
for the generic parameters for determining interior mutability
|
||||||
|
|
||||||
|
**Default Value:** `["bytes::Bytes"]` (`Vec<String>`)
|
||||||
|
|
||||||
|
* [mutable_key](https://rust-lang.github.io/rust-clippy/master/index.html#mutable_key)
|
||||||
|
|
||||||
|
|
||||||
|
### allow-mixed-uninlined-format-args
|
||||||
|
Whether to allow mixed uninlined format args, e.g. `format!("{} {}", a, foo.bar)`
|
||||||
|
|
||||||
|
**Default Value:** `true` (`bool`)
|
||||||
|
|
||||||
|
* [uninlined_format_args](https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args)
|
||||||
|
|
||||||
|
|
||||||
|
### suppress-restriction-lint-in-const
|
||||||
|
In same
|
||||||
|
cases the restructured operation might not be unavoidable, as the
|
||||||
|
suggested counterparts are unavailable in constant code. This
|
||||||
|
configuration will cause restriction lints to trigger even
|
||||||
|
if no suggestion can be made.
|
||||||
|
|
||||||
|
**Default Value:** `false` (`bool`)
|
||||||
|
|
||||||
|
* [indexing_slicing](https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "clippy_lints"
|
name = "clippy_lints"
|
||||||
version = "0.1.68"
|
version = "0.1.69"
|
||||||
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
||||||
repository = "https://github.com/rust-lang/rust-clippy"
|
repository = "https://github.com/rust-lang/rust-clippy"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::macros::{find_assert_eq_args, root_macro_call_first_node};
|
use clippy_utils::macros::{find_assert_eq_args, root_macro_call_first_node};
|
||||||
use clippy_utils::{diagnostics::span_lint_and_sugg, ty::implements_trait};
|
use clippy_utils::ty::{implements_trait, is_copy};
|
||||||
use rustc_ast::ast::LitKind;
|
use rustc_ast::ast::LitKind;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{Expr, ExprKind, Lit};
|
use rustc_hir::{Expr, ExprKind, Lit};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty::{self, Ty};
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
|
|
||||||
@ -43,9 +44,7 @@ fn is_bool_lit(e: &Expr<'_>) -> bool {
|
|||||||
) && !e.span.from_expansion()
|
) && !e.span.from_expansion()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_impl_not_trait_with_bool_out(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
|
fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||||
let ty = cx.typeck_results().expr_ty(e);
|
|
||||||
|
|
||||||
cx.tcx
|
cx.tcx
|
||||||
.lang_items()
|
.lang_items()
|
||||||
.not_trait()
|
.not_trait()
|
||||||
@ -77,31 +76,57 @@ impl<'tcx> LateLintPass<'tcx> for BoolAssertComparison {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let Some ((a, b, _)) = find_assert_eq_args(cx, expr, macro_call.expn) else { return };
|
let Some ((a, b, _)) = find_assert_eq_args(cx, expr, macro_call.expn) else { return };
|
||||||
if !(is_bool_lit(a) ^ is_bool_lit(b)) {
|
|
||||||
|
let a_span = a.span.source_callsite();
|
||||||
|
let b_span = b.span.source_callsite();
|
||||||
|
|
||||||
|
let (lit_span, non_lit_expr) = match (is_bool_lit(a), is_bool_lit(b)) {
|
||||||
|
// assert_eq!(true, b)
|
||||||
|
// ^^^^^^
|
||||||
|
(true, false) => (a_span.until(b_span), b),
|
||||||
|
// assert_eq!(a, true)
|
||||||
|
// ^^^^^^
|
||||||
|
(false, true) => (b_span.with_lo(a_span.hi()), a),
|
||||||
// If there are two boolean arguments, we definitely don't understand
|
// If there are two boolean arguments, we definitely don't understand
|
||||||
// what's going on, so better leave things as is...
|
// what's going on, so better leave things as is...
|
||||||
//
|
//
|
||||||
// Or there is simply no boolean and then we can leave things as is!
|
// Or there is simply no boolean and then we can leave things as is!
|
||||||
return;
|
_ => return,
|
||||||
}
|
};
|
||||||
|
|
||||||
if !is_impl_not_trait_with_bool_out(cx, a) || !is_impl_not_trait_with_bool_out(cx, b) {
|
let non_lit_ty = cx.typeck_results().expr_ty(non_lit_expr);
|
||||||
|
|
||||||
|
if !is_impl_not_trait_with_bool_out(cx, non_lit_ty) {
|
||||||
// At this point the expression which is not a boolean
|
// At this point the expression which is not a boolean
|
||||||
// literal does not implement Not trait with a bool output,
|
// literal does not implement Not trait with a bool output,
|
||||||
// so we cannot suggest to rewrite our code
|
// so we cannot suggest to rewrite our code
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !is_copy(cx, non_lit_ty) {
|
||||||
|
// Only lint with types that are `Copy` because `assert!(x)` takes
|
||||||
|
// ownership of `x` whereas `assert_eq(x, true)` does not
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let macro_name = macro_name.as_str();
|
let macro_name = macro_name.as_str();
|
||||||
let non_eq_mac = ¯o_name[..macro_name.len() - 3];
|
let non_eq_mac = ¯o_name[..macro_name.len() - 3];
|
||||||
span_lint_and_sugg(
|
span_lint_and_then(
|
||||||
cx,
|
cx,
|
||||||
BOOL_ASSERT_COMPARISON,
|
BOOL_ASSERT_COMPARISON,
|
||||||
macro_call.span,
|
macro_call.span,
|
||||||
&format!("used `{macro_name}!` with a literal bool"),
|
&format!("used `{macro_name}!` with a literal bool"),
|
||||||
"replace it with",
|
|diag| {
|
||||||
format!("{non_eq_mac}!(..)"),
|
// assert_eq!(...)
|
||||||
Applicability::MaybeIncorrect,
|
// ^^^^^^^^^
|
||||||
|
let name_span = cx.sess().source_map().span_until_char(macro_call.span, '!');
|
||||||
|
|
||||||
|
diag.multipart_suggestion(
|
||||||
|
format!("replace it with `{non_eq_mac}!(..)`"),
|
||||||
|
vec![(name_span, non_eq_mac.to_string()), (lit_span, String::new())],
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
use clippy_utils::consts::{constant, Constant};
|
use clippy_utils::consts::{constant, Constant};
|
||||||
use clippy_utils::diagnostics::span_lint;
|
use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
|
||||||
use clippy_utils::expr_or_init;
|
use clippy_utils::expr_or_init;
|
||||||
|
use clippy_utils::source::snippet;
|
||||||
use clippy_utils::ty::{get_discriminant_value, is_isize_or_usize};
|
use clippy_utils::ty::{get_discriminant_value, is_isize_or_usize};
|
||||||
|
use rustc_errors::{Applicability, SuggestionStyle};
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::{BinOpKind, Expr, ExprKind};
|
use rustc_hir::{BinOpKind, Expr, ExprKind};
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
use rustc_middle::ty::{self, FloatTy, Ty};
|
use rustc_middle::ty::{self, FloatTy, Ty};
|
||||||
|
use rustc_span::Span;
|
||||||
use rustc_target::abi::IntegerType;
|
use rustc_target::abi::IntegerType;
|
||||||
|
|
||||||
use super::{utils, CAST_ENUM_TRUNCATION, CAST_POSSIBLE_TRUNCATION};
|
use super::{utils, CAST_ENUM_TRUNCATION, CAST_POSSIBLE_TRUNCATION};
|
||||||
@ -74,7 +77,14 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {
|
pub(super) fn check(
|
||||||
|
cx: &LateContext<'_>,
|
||||||
|
expr: &Expr<'_>,
|
||||||
|
cast_expr: &Expr<'_>,
|
||||||
|
cast_from: Ty<'_>,
|
||||||
|
cast_to: Ty<'_>,
|
||||||
|
cast_to_span: Span,
|
||||||
|
) {
|
||||||
let msg = match (cast_from.kind(), cast_to.is_integral()) {
|
let msg = match (cast_from.kind(), cast_to.is_integral()) {
|
||||||
(ty::Int(_) | ty::Uint(_), true) => {
|
(ty::Int(_) | ty::Uint(_), true) => {
|
||||||
let from_nbits = apply_reductions(
|
let from_nbits = apply_reductions(
|
||||||
@ -139,7 +149,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
format!("casting `{cast_from}` to `{cast_to}` may truncate the value{suffix}",)
|
format!("casting `{cast_from}` to `{cast_to}` may truncate the value{suffix}")
|
||||||
},
|
},
|
||||||
|
|
||||||
(ty::Float(_), true) => {
|
(ty::Float(_), true) => {
|
||||||
@ -153,5 +163,19 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
|
|||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
span_lint(cx, CAST_POSSIBLE_TRUNCATION, expr.span, &msg);
|
let name_of_cast_from = snippet(cx, cast_expr.span, "..");
|
||||||
|
let cast_to_snip = snippet(cx, cast_to_span, "..");
|
||||||
|
let suggestion = format!("{cast_to_snip}::try_from({name_of_cast_from})");
|
||||||
|
|
||||||
|
span_lint_and_then(cx, CAST_POSSIBLE_TRUNCATION, expr.span, &msg, |diag| {
|
||||||
|
diag.help("if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...");
|
||||||
|
diag.span_suggestion_with_style(
|
||||||
|
expr.span,
|
||||||
|
"... or use `try_from` and handle the error accordingly",
|
||||||
|
suggestion,
|
||||||
|
Applicability::Unspecified,
|
||||||
|
// always show the suggestion in a separate line
|
||||||
|
SuggestionStyle::ShowAlways,
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,8 @@ declare_clippy_lint! {
|
|||||||
/// ### What it does
|
/// ### What it does
|
||||||
/// Checks for casts between numerical types that may
|
/// Checks for casts between numerical types that may
|
||||||
/// truncate large values. This is expected behavior, so the cast is `Allow` by
|
/// truncate large values. This is expected behavior, so the cast is `Allow` by
|
||||||
/// default.
|
/// default. It suggests user either explicitly ignore the lint,
|
||||||
|
/// or use `try_from()` and handle the truncation, default, or panic explicitly.
|
||||||
///
|
///
|
||||||
/// ### Why is this bad?
|
/// ### Why is this bad?
|
||||||
/// In some problem domains, it is good practice to avoid
|
/// In some problem domains, it is good practice to avoid
|
||||||
@ -93,6 +94,21 @@ declare_clippy_lint! {
|
|||||||
/// x as u8
|
/// x as u8
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
/// Use instead:
|
||||||
|
/// ```
|
||||||
|
/// fn as_u8(x: u64) -> u8 {
|
||||||
|
/// if let Ok(x) = u8::try_from(x) {
|
||||||
|
/// x
|
||||||
|
/// } else {
|
||||||
|
/// todo!();
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// // Or
|
||||||
|
/// #[allow(clippy::cast_possible_truncation)]
|
||||||
|
/// fn as_u16(x: u64) -> u16 {
|
||||||
|
/// x as u16
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
#[clippy::version = "pre 1.29.0"]
|
#[clippy::version = "pre 1.29.0"]
|
||||||
pub CAST_POSSIBLE_TRUNCATION,
|
pub CAST_POSSIBLE_TRUNCATION,
|
||||||
pedantic,
|
pedantic,
|
||||||
@ -712,7 +728,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
|
|||||||
fn_to_numeric_cast_with_truncation::check(cx, expr, cast_expr, cast_from, cast_to);
|
fn_to_numeric_cast_with_truncation::check(cx, expr, cast_expr, cast_from, cast_to);
|
||||||
|
|
||||||
if cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) {
|
if cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) {
|
||||||
cast_possible_truncation::check(cx, expr, cast_expr, cast_from, cast_to);
|
cast_possible_truncation::check(cx, expr, cast_expr, cast_from, cast_to, cast_to_hir.span);
|
||||||
if cast_from.is_numeric() {
|
if cast_from.is_numeric() {
|
||||||
cast_possible_wrap::check(cx, expr, cast_from, cast_to);
|
cast_possible_wrap::check(cx, expr, cast_from, cast_to);
|
||||||
cast_precision_loss::check(cx, expr, cast_from, cast_to);
|
cast_precision_loss::check(cx, expr, cast_from, cast_to);
|
||||||
|
@ -422,6 +422,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
|
|||||||
crate::module_style::MOD_MODULE_FILES_INFO,
|
crate::module_style::MOD_MODULE_FILES_INFO,
|
||||||
crate::module_style::SELF_NAMED_MODULE_FILES_INFO,
|
crate::module_style::SELF_NAMED_MODULE_FILES_INFO,
|
||||||
crate::multi_assignments::MULTI_ASSIGNMENTS_INFO,
|
crate::multi_assignments::MULTI_ASSIGNMENTS_INFO,
|
||||||
|
crate::multiple_unsafe_ops_per_block::MULTIPLE_UNSAFE_OPS_PER_BLOCK_INFO,
|
||||||
crate::mut_key::MUTABLE_KEY_TYPE_INFO,
|
crate::mut_key::MUTABLE_KEY_TYPE_INFO,
|
||||||
crate::mut_mut::MUT_MUT_INFO,
|
crate::mut_mut::MUT_MUT_INFO,
|
||||||
crate::mut_reference::UNNECESSARY_MUT_PASSED_INFO,
|
crate::mut_reference::UNNECESSARY_MUT_PASSED_INFO,
|
||||||
|
@ -251,7 +251,7 @@ declare_clippy_lint! {
|
|||||||
/// unimplemented!();
|
/// unimplemented!();
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[clippy::version = "1.66.0"]
|
#[clippy::version = "1.67.0"]
|
||||||
pub UNNECESSARY_SAFETY_DOC,
|
pub UNNECESSARY_SAFETY_DOC,
|
||||||
restriction,
|
restriction,
|
||||||
"`pub fn` or `pub trait` with `# Safety` docs"
|
"`pub fn` or `pub trait` with `# Safety` docs"
|
||||||
|
@ -277,7 +277,7 @@ impl LateLintPass<'_> for EnumVariantNames {
|
|||||||
Some(c) if is_word_beginning(c) => span_lint(
|
Some(c) if is_word_beginning(c) => span_lint(
|
||||||
cx,
|
cx,
|
||||||
MODULE_NAME_REPETITIONS,
|
MODULE_NAME_REPETITIONS,
|
||||||
item.span,
|
item.ident.span,
|
||||||
"item name starts with its containing module's name",
|
"item name starts with its containing module's name",
|
||||||
),
|
),
|
||||||
_ => (),
|
_ => (),
|
||||||
@ -287,7 +287,7 @@ impl LateLintPass<'_> for EnumVariantNames {
|
|||||||
span_lint(
|
span_lint(
|
||||||
cx,
|
cx,
|
||||||
MODULE_NAME_REPETITIONS,
|
MODULE_NAME_REPETITIONS,
|
||||||
item.span,
|
item.ident.span,
|
||||||
"item name ends with its containing module's name",
|
"item name ends with its containing module's name",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ declare_clippy_lint! {
|
|||||||
/// let _ = unsafe { Box::from_raw(ptr as *mut usize) };
|
/// let _ = unsafe { Box::from_raw(ptr as *mut usize) };
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
#[clippy::version = "1.66.0"]
|
#[clippy::version = "1.67.0"]
|
||||||
pub FROM_RAW_WITH_VOID_PTR,
|
pub FROM_RAW_WITH_VOID_PTR,
|
||||||
suspicious,
|
suspicious,
|
||||||
"creating a `Box` from a void raw pointer"
|
"creating a `Box` from a void raw pointer"
|
||||||
|
@ -59,7 +59,7 @@ declare_clippy_lint! {
|
|||||||
///
|
///
|
||||||
/// [`Duration`]: std::time::Duration
|
/// [`Duration`]: std::time::Duration
|
||||||
/// [`Instant::now()`]: std::time::Instant::now;
|
/// [`Instant::now()`]: std::time::Instant::now;
|
||||||
#[clippy::version = "1.65.0"]
|
#[clippy::version = "1.67.0"]
|
||||||
pub UNCHECKED_DURATION_SUBTRACTION,
|
pub UNCHECKED_DURATION_SUBTRACTION,
|
||||||
pedantic,
|
pedantic,
|
||||||
"finds unchecked subtraction of a 'Duration' from an 'Instant'"
|
"finds unchecked subtraction of a 'Duration' from an 'Instant'"
|
||||||
|
@ -84,7 +84,7 @@ declare_clippy_lint! {
|
|||||||
/// let _ = foo().await;
|
/// let _ = foo().await;
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[clippy::version = "1.66"]
|
#[clippy::version = "1.67.0"]
|
||||||
pub LET_UNDERSCORE_FUTURE,
|
pub LET_UNDERSCORE_FUTURE,
|
||||||
suspicious,
|
suspicious,
|
||||||
"non-binding `let` on a future"
|
"non-binding `let` on a future"
|
||||||
|
@ -198,6 +198,7 @@ mod missing_trait_methods;
|
|||||||
mod mixed_read_write_in_expression;
|
mod mixed_read_write_in_expression;
|
||||||
mod module_style;
|
mod module_style;
|
||||||
mod multi_assignments;
|
mod multi_assignments;
|
||||||
|
mod multiple_unsafe_ops_per_block;
|
||||||
mod mut_key;
|
mod mut_key;
|
||||||
mod mut_mut;
|
mod mut_mut;
|
||||||
mod mut_reference;
|
mod mut_reference;
|
||||||
@ -908,6 +909,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||||||
store.register_late_pass(|_| Box::new(fn_null_check::FnNullCheck));
|
store.register_late_pass(|_| Box::new(fn_null_check::FnNullCheck));
|
||||||
store.register_late_pass(|_| Box::new(permissions_set_readonly_false::PermissionsSetReadonlyFalse));
|
store.register_late_pass(|_| Box::new(permissions_set_readonly_false::PermissionsSetReadonlyFalse));
|
||||||
store.register_late_pass(|_| Box::new(size_of_ref::SizeOfRef));
|
store.register_late_pass(|_| Box::new(size_of_ref::SizeOfRef));
|
||||||
|
store.register_late_pass(|_| Box::new(multiple_unsafe_ops_per_block::MultipleUnsafeOpsPerBlock));
|
||||||
// add lints here, do not remove this comment, it's used in `new_lint`
|
// add lints here, do not remove this comment, it's used in `new_lint`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ declare_clippy_lint! {
|
|||||||
/// 'A'.is_ascii_uppercase();
|
/// 'A'.is_ascii_uppercase();
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[clippy::version = "1.66.0"]
|
#[clippy::version = "1.67.0"]
|
||||||
pub MANUAL_IS_ASCII_CHECK,
|
pub MANUAL_IS_ASCII_CHECK,
|
||||||
style,
|
style,
|
||||||
"use dedicated method to check ascii range"
|
"use dedicated method to check ascii range"
|
||||||
|
@ -3102,7 +3102,7 @@ declare_clippy_lint! {
|
|||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[clippy::version = "1.66.0"]
|
#[clippy::version = "1.67.0"]
|
||||||
pub SEEK_FROM_CURRENT,
|
pub SEEK_FROM_CURRENT,
|
||||||
complexity,
|
complexity,
|
||||||
"use dedicated method for seek from current position"
|
"use dedicated method for seek from current position"
|
||||||
@ -3133,7 +3133,7 @@ declare_clippy_lint! {
|
|||||||
/// t.rewind();
|
/// t.rewind();
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[clippy::version = "1.66.0"]
|
#[clippy::version = "1.67.0"]
|
||||||
pub SEEK_TO_START_INSTEAD_OF_REWIND,
|
pub SEEK_TO_START_INSTEAD_OF_REWIND,
|
||||||
complexity,
|
complexity,
|
||||||
"jumping to the start of stream using `seek` method"
|
"jumping to the start of stream using `seek` method"
|
||||||
|
@ -94,7 +94,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingTraitMethods {
|
|||||||
"implement the method",
|
"implement the method",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,185 @@
|
|||||||
|
use clippy_utils::{
|
||||||
|
diagnostics::span_lint_and_then,
|
||||||
|
visitors::{for_each_expr_with_closures, Descend, Visitable},
|
||||||
|
};
|
||||||
|
use core::ops::ControlFlow::Continue;
|
||||||
|
use hir::{
|
||||||
|
def::{DefKind, Res},
|
||||||
|
BlockCheckMode, ExprKind, QPath, UnOp, Unsafety,
|
||||||
|
};
|
||||||
|
use rustc_ast::Mutability;
|
||||||
|
use rustc_hir as hir;
|
||||||
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
|
use rustc_span::Span;
|
||||||
|
|
||||||
|
declare_clippy_lint! {
|
||||||
|
/// ### What it does
|
||||||
|
/// Checks for `unsafe` blocks that contain more than one unsafe operation.
|
||||||
|
///
|
||||||
|
/// ### Why is this bad?
|
||||||
|
/// Combined with `undocumented_unsafe_blocks`,
|
||||||
|
/// this lint ensures that each unsafe operation must be independently justified.
|
||||||
|
/// Combined with `unused_unsafe`, this lint also ensures
|
||||||
|
/// elimination of unnecessary unsafe blocks through refactoring.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
/// ```rust
|
||||||
|
/// /// Reads a `char` from the given pointer.
|
||||||
|
/// ///
|
||||||
|
/// /// # Safety
|
||||||
|
/// ///
|
||||||
|
/// /// `ptr` must point to four consecutive, initialized bytes which
|
||||||
|
/// /// form a valid `char` when interpreted in the native byte order.
|
||||||
|
/// fn read_char(ptr: *const u8) -> char {
|
||||||
|
/// // SAFETY: The caller has guaranteed that the value pointed
|
||||||
|
/// // to by `bytes` is a valid `char`.
|
||||||
|
/// unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
/// Use instead:
|
||||||
|
/// ```rust
|
||||||
|
/// /// Reads a `char` from the given pointer.
|
||||||
|
/// ///
|
||||||
|
/// /// # Safety
|
||||||
|
/// ///
|
||||||
|
/// /// - `ptr` must be 4-byte aligned, point to four consecutive
|
||||||
|
/// /// initialized bytes, and be valid for reads of 4 bytes.
|
||||||
|
/// /// - The bytes pointed to by `ptr` must represent a valid
|
||||||
|
/// /// `char` when interpreted in the native byte order.
|
||||||
|
/// fn read_char(ptr: *const u8) -> char {
|
||||||
|
/// // SAFETY: `ptr` is 4-byte aligned, points to four consecutive
|
||||||
|
/// // initialized bytes, and is valid for reads of 4 bytes.
|
||||||
|
/// let int_value = unsafe { *ptr.cast::<u32>() };
|
||||||
|
///
|
||||||
|
/// // SAFETY: The caller has guaranteed that the four bytes
|
||||||
|
/// // pointed to by `bytes` represent a valid `char`.
|
||||||
|
/// unsafe { char::from_u32_unchecked(int_value) }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[clippy::version = "1.68.0"]
|
||||||
|
pub MULTIPLE_UNSAFE_OPS_PER_BLOCK,
|
||||||
|
restriction,
|
||||||
|
"more than one unsafe operation per `unsafe` block"
|
||||||
|
}
|
||||||
|
declare_lint_pass!(MultipleUnsafeOpsPerBlock => [MULTIPLE_UNSAFE_OPS_PER_BLOCK]);
|
||||||
|
|
||||||
|
impl<'tcx> LateLintPass<'tcx> for MultipleUnsafeOpsPerBlock {
|
||||||
|
fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'_>) {
|
||||||
|
if !matches!(block.rules, BlockCheckMode::UnsafeBlock(_)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let mut unsafe_ops = vec![];
|
||||||
|
collect_unsafe_exprs(cx, block, &mut unsafe_ops);
|
||||||
|
if unsafe_ops.len() > 1 {
|
||||||
|
span_lint_and_then(
|
||||||
|
cx,
|
||||||
|
MULTIPLE_UNSAFE_OPS_PER_BLOCK,
|
||||||
|
block.span,
|
||||||
|
&format!(
|
||||||
|
"this `unsafe` block contains {} unsafe operations, expected only one",
|
||||||
|
unsafe_ops.len()
|
||||||
|
),
|
||||||
|
|diag| {
|
||||||
|
for (msg, span) in unsafe_ops {
|
||||||
|
diag.span_note(span, msg);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn collect_unsafe_exprs<'tcx>(
|
||||||
|
cx: &LateContext<'tcx>,
|
||||||
|
node: impl Visitable<'tcx>,
|
||||||
|
unsafe_ops: &mut Vec<(&'static str, Span)>,
|
||||||
|
) {
|
||||||
|
for_each_expr_with_closures(cx, node, |expr| {
|
||||||
|
match expr.kind {
|
||||||
|
ExprKind::InlineAsm(_) => unsafe_ops.push(("inline assembly used here", expr.span)),
|
||||||
|
|
||||||
|
ExprKind::Field(e, _) => {
|
||||||
|
if cx.typeck_results().expr_ty(e).is_union() {
|
||||||
|
unsafe_ops.push(("union field access occurs here", expr.span));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ExprKind::Path(QPath::Resolved(
|
||||||
|
_,
|
||||||
|
hir::Path {
|
||||||
|
res: Res::Def(DefKind::Static(Mutability::Mut), _),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
)) => {
|
||||||
|
unsafe_ops.push(("access of a mutable static occurs here", expr.span));
|
||||||
|
},
|
||||||
|
|
||||||
|
ExprKind::Unary(UnOp::Deref, e) if cx.typeck_results().expr_ty_adjusted(e).is_unsafe_ptr() => {
|
||||||
|
unsafe_ops.push(("raw pointer dereference occurs here", expr.span));
|
||||||
|
},
|
||||||
|
|
||||||
|
ExprKind::Call(path_expr, _) => match path_expr.kind {
|
||||||
|
ExprKind::Path(QPath::Resolved(
|
||||||
|
_,
|
||||||
|
hir::Path {
|
||||||
|
res: Res::Def(kind, def_id),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
)) if kind.is_fn_like() => {
|
||||||
|
let sig = cx.tcx.fn_sig(*def_id);
|
||||||
|
if sig.0.unsafety() == Unsafety::Unsafe {
|
||||||
|
unsafe_ops.push(("unsafe function call occurs here", expr.span));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ExprKind::Path(QPath::TypeRelative(..)) => {
|
||||||
|
if let Some(sig) = cx
|
||||||
|
.typeck_results()
|
||||||
|
.type_dependent_def_id(path_expr.hir_id)
|
||||||
|
.map(|def_id| cx.tcx.fn_sig(def_id))
|
||||||
|
{
|
||||||
|
if sig.0.unsafety() == Unsafety::Unsafe {
|
||||||
|
unsafe_ops.push(("unsafe function call occurs here", expr.span));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_ => {},
|
||||||
|
},
|
||||||
|
|
||||||
|
ExprKind::MethodCall(..) => {
|
||||||
|
if let Some(sig) = cx
|
||||||
|
.typeck_results()
|
||||||
|
.type_dependent_def_id(expr.hir_id)
|
||||||
|
.map(|def_id| cx.tcx.fn_sig(def_id))
|
||||||
|
{
|
||||||
|
if sig.0.unsafety() == Unsafety::Unsafe {
|
||||||
|
unsafe_ops.push(("unsafe method call occurs here", expr.span));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ExprKind::AssignOp(_, lhs, rhs) | ExprKind::Assign(lhs, rhs, _) => {
|
||||||
|
if matches!(
|
||||||
|
lhs.kind,
|
||||||
|
ExprKind::Path(QPath::Resolved(
|
||||||
|
_,
|
||||||
|
hir::Path {
|
||||||
|
res: Res::Def(DefKind::Static(Mutability::Mut), _),
|
||||||
|
..
|
||||||
|
}
|
||||||
|
))
|
||||||
|
) {
|
||||||
|
unsafe_ops.push(("modification of a mutable static occurs here", expr.span));
|
||||||
|
collect_unsafe_exprs(cx, rhs, unsafe_ops);
|
||||||
|
return Continue(Descend::No);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_ => {},
|
||||||
|
};
|
||||||
|
|
||||||
|
Continue::<(), _>(Descend::Yes)
|
||||||
|
});
|
||||||
|
}
|
@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId;
|
|||||||
use rustc_hir::hir_id::HirIdMap;
|
use rustc_hir::hir_id::HirIdMap;
|
||||||
use rustc_hir::{Body, Expr, ExprKind, HirId, ImplItem, ImplItemKind, Node, PatKind, TraitItem, TraitItemKind};
|
use rustc_hir::{Body, Expr, ExprKind, HirId, ImplItem, ImplItemKind, Node, PatKind, TraitItem, TraitItemKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
|
use rustc_middle::ty::subst::{EarlyBinder, GenericArgKind, SubstsRef};
|
||||||
use rustc_middle::ty::{self, ConstKind};
|
use rustc_middle::ty::{self, ConstKind};
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
use rustc_span::symbol::{kw, Ident};
|
use rustc_span::symbol::{kw, Ident};
|
||||||
@ -244,7 +244,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
|
|||||||
})) => {
|
})) => {
|
||||||
#[allow(trivial_casts)]
|
#[allow(trivial_casts)]
|
||||||
if let Some(Node::Item(item)) = get_parent_node(cx.tcx, owner_id.into())
|
if let Some(Node::Item(item)) = get_parent_node(cx.tcx, owner_id.into())
|
||||||
&& let Some(trait_ref) = cx.tcx.impl_trait_ref(item.owner_id).map(|t| t.subst_identity())
|
&& let Some(trait_ref) = cx.tcx.impl_trait_ref(item.owner_id).map(EarlyBinder::subst_identity)
|
||||||
&& let Some(trait_item_id) = cx.tcx.associated_item(owner_id).trait_item_def_id
|
&& let Some(trait_item_id) = cx.tcx.associated_item(owner_id).trait_item_def_id
|
||||||
{
|
{
|
||||||
(
|
(
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
|
use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
|
||||||
use clippy_utils::source::{snippet_opt, snippet_with_context};
|
use clippy_utils::source::{snippet_opt, snippet_with_context};
|
||||||
use clippy_utils::visitors::{for_each_expr, Descend};
|
use clippy_utils::visitors::{for_each_expr, Descend};
|
||||||
use clippy_utils::{fn_def_id, path_to_local_id};
|
use clippy_utils::{fn_def_id, path_to_local_id, span_find_starting_semi};
|
||||||
use core::ops::ControlFlow;
|
use core::ops::ControlFlow;
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
@ -151,7 +151,7 @@ impl<'tcx> LateLintPass<'tcx> for Return {
|
|||||||
kind: FnKind<'tcx>,
|
kind: FnKind<'tcx>,
|
||||||
_: &'tcx FnDecl<'tcx>,
|
_: &'tcx FnDecl<'tcx>,
|
||||||
body: &'tcx Body<'tcx>,
|
body: &'tcx Body<'tcx>,
|
||||||
_: Span,
|
sp: Span,
|
||||||
_: HirId,
|
_: HirId,
|
||||||
) {
|
) {
|
||||||
match kind {
|
match kind {
|
||||||
@ -166,14 +166,14 @@ impl<'tcx> LateLintPass<'tcx> for Return {
|
|||||||
check_final_expr(cx, body.value, vec![], replacement);
|
check_final_expr(cx, body.value, vec![], replacement);
|
||||||
},
|
},
|
||||||
FnKind::ItemFn(..) | FnKind::Method(..) => {
|
FnKind::ItemFn(..) | FnKind::Method(..) => {
|
||||||
check_block_return(cx, &body.value.kind, vec![]);
|
check_block_return(cx, &body.value.kind, sp, vec![]);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if `expr` is a block, check if there are needless returns in it
|
// if `expr` is a block, check if there are needless returns in it
|
||||||
fn check_block_return<'tcx>(cx: &LateContext<'tcx>, expr_kind: &ExprKind<'tcx>, semi_spans: Vec<Span>) {
|
fn check_block_return<'tcx>(cx: &LateContext<'tcx>, expr_kind: &ExprKind<'tcx>, sp: Span, mut semi_spans: Vec<Span>) {
|
||||||
if let ExprKind::Block(block, _) = expr_kind {
|
if let ExprKind::Block(block, _) = expr_kind {
|
||||||
if let Some(block_expr) = block.expr {
|
if let Some(block_expr) = block.expr {
|
||||||
check_final_expr(cx, block_expr, semi_spans, RetReplacement::Empty);
|
check_final_expr(cx, block_expr, semi_spans, RetReplacement::Empty);
|
||||||
@ -183,12 +183,14 @@ fn check_block_return<'tcx>(cx: &LateContext<'tcx>, expr_kind: &ExprKind<'tcx>,
|
|||||||
check_final_expr(cx, expr, semi_spans, RetReplacement::Empty);
|
check_final_expr(cx, expr, semi_spans, RetReplacement::Empty);
|
||||||
},
|
},
|
||||||
StmtKind::Semi(semi_expr) => {
|
StmtKind::Semi(semi_expr) => {
|
||||||
let mut semi_spans_and_this_one = semi_spans;
|
// Remove ending semicolons and any whitespace ' ' in between.
|
||||||
// we only want the span containing the semicolon so we can remove it later. From `entry.rs:382`
|
// Without `return`, the suggestion might not compile if the semicolon is retained
|
||||||
if let Some(semicolon_span) = stmt.span.trim_start(semi_expr.span) {
|
if let Some(semi_span) = stmt.span.trim_start(semi_expr.span) {
|
||||||
semi_spans_and_this_one.push(semicolon_span);
|
let semi_span_to_remove =
|
||||||
check_final_expr(cx, semi_expr, semi_spans_and_this_one, RetReplacement::Empty);
|
span_find_starting_semi(cx.sess().source_map(), semi_span.with_hi(sp.hi()));
|
||||||
|
semi_spans.push(semi_span_to_remove);
|
||||||
}
|
}
|
||||||
|
check_final_expr(cx, semi_expr, semi_spans, RetReplacement::Empty);
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
@ -231,9 +233,9 @@ fn check_final_expr<'tcx>(
|
|||||||
emit_return_lint(cx, ret_span, semi_spans, inner.as_ref().map(|i| i.span), replacement);
|
emit_return_lint(cx, ret_span, semi_spans, inner.as_ref().map(|i| i.span), replacement);
|
||||||
},
|
},
|
||||||
ExprKind::If(_, then, else_clause_opt) => {
|
ExprKind::If(_, then, else_clause_opt) => {
|
||||||
check_block_return(cx, &then.kind, semi_spans.clone());
|
check_block_return(cx, &then.kind, peeled_drop_expr.span, semi_spans.clone());
|
||||||
if let Some(else_clause) = else_clause_opt {
|
if let Some(else_clause) = else_clause_opt {
|
||||||
check_block_return(cx, &else_clause.kind, semi_spans);
|
check_block_return(cx, &else_clause.kind, peeled_drop_expr.span, semi_spans);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// a match expr, check all arms
|
// a match expr, check all arms
|
||||||
@ -246,7 +248,7 @@ fn check_final_expr<'tcx>(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
// if it's a whole block, check it
|
// if it's a whole block, check it
|
||||||
other_expr_kind => check_block_return(cx, other_expr_kind, semi_spans),
|
other_expr_kind => check_block_return(cx, other_expr_kind, peeled_drop_expr.span, semi_spans),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ declare_clippy_lint! {
|
|||||||
/// ### What it does
|
/// ### What it does
|
||||||
/// Warns for a Bitwise XOR (`^`) operator being probably confused as a powering. It will not trigger if any of the numbers are not in decimal.
|
/// Warns for a Bitwise XOR (`^`) operator being probably confused as a powering. It will not trigger if any of the numbers are not in decimal.
|
||||||
/// ### Why is this bad?
|
/// ### Why is this bad?
|
||||||
/// It's most probably a typo and may lead to unexpected behaviours.
|
/// It's most probably a typo and may lead to unexpected behaviours.
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// let x = 3_i32 ^ 4_i32;
|
/// let x = 3_i32 ^ 4_i32;
|
||||||
@ -18,7 +18,7 @@ declare_clippy_lint! {
|
|||||||
/// ```rust
|
/// ```rust
|
||||||
/// let x = 3_i32.pow(4);
|
/// let x = 3_i32.pow(4);
|
||||||
/// ```
|
/// ```
|
||||||
#[clippy::version = "1.66.0"]
|
#[clippy::version = "1.67.0"]
|
||||||
pub SUSPICIOUS_XOR_USED_AS_POW,
|
pub SUSPICIOUS_XOR_USED_AS_POW,
|
||||||
restriction,
|
restriction,
|
||||||
"XOR (`^`) operator possibly used as exponentiation operator"
|
"XOR (`^`) operator possibly used as exponentiation operator"
|
||||||
|
@ -479,7 +479,10 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
|
|||||||
// - char conversions (https://github.com/rust-lang/rust/issues/89259)
|
// - char conversions (https://github.com/rust-lang/rust/issues/89259)
|
||||||
let const_context = in_constant(cx, e.hir_id);
|
let const_context = in_constant(cx, e.hir_id);
|
||||||
|
|
||||||
let from_ty = cx.typeck_results().expr_ty_adjusted(arg);
|
let (from_ty, from_ty_adjusted) = match cx.typeck_results().expr_adjustments(arg) {
|
||||||
|
[] => (cx.typeck_results().expr_ty(arg), false),
|
||||||
|
[.., a] => (a.target, true),
|
||||||
|
};
|
||||||
// Adjustments for `to_ty` happen after the call to `transmute`, so don't use them.
|
// Adjustments for `to_ty` happen after the call to `transmute`, so don't use them.
|
||||||
let to_ty = cx.typeck_results().expr_ty(e);
|
let to_ty = cx.typeck_results().expr_ty(e);
|
||||||
|
|
||||||
@ -506,7 +509,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if !linted {
|
if !linted {
|
||||||
transmutes_expressible_as_ptr_casts::check(cx, e, from_ty, to_ty, arg);
|
transmutes_expressible_as_ptr_casts::check(cx, e, from_ty, from_ty_adjusted, to_ty, arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
use super::utils::can_be_expressed_as_pointer_cast;
|
use super::utils::check_cast;
|
||||||
use super::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS;
|
use super::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS;
|
||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
use clippy_utils::sugg;
|
use clippy_utils::sugg::Sugg;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::Expr;
|
use rustc_hir::Expr;
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::{cast::CastKind, Ty};
|
||||||
|
|
||||||
/// Checks for `transmutes_expressible_as_ptr_casts` lint.
|
/// Checks for `transmutes_expressible_as_ptr_casts` lint.
|
||||||
/// Returns `true` if it's triggered, otherwise returns `false`.
|
/// Returns `true` if it's triggered, otherwise returns `false`.
|
||||||
@ -13,24 +13,40 @@ pub(super) fn check<'tcx>(
|
|||||||
cx: &LateContext<'tcx>,
|
cx: &LateContext<'tcx>,
|
||||||
e: &'tcx Expr<'_>,
|
e: &'tcx Expr<'_>,
|
||||||
from_ty: Ty<'tcx>,
|
from_ty: Ty<'tcx>,
|
||||||
|
from_ty_adjusted: bool,
|
||||||
to_ty: Ty<'tcx>,
|
to_ty: Ty<'tcx>,
|
||||||
arg: &'tcx Expr<'_>,
|
arg: &'tcx Expr<'_>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if can_be_expressed_as_pointer_cast(cx, e, from_ty, to_ty) {
|
use CastKind::{AddrPtrCast, ArrayPtrCast, FnPtrAddrCast, FnPtrPtrCast, PtrAddrCast, PtrPtrCast};
|
||||||
span_lint_and_then(
|
let mut app = Applicability::MachineApplicable;
|
||||||
cx,
|
let sugg = match check_cast(cx, e, from_ty, to_ty) {
|
||||||
TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS,
|
Some(PtrPtrCast | AddrPtrCast | ArrayPtrCast | FnPtrPtrCast | FnPtrAddrCast) => {
|
||||||
e.span,
|
Sugg::hir_with_context(cx, arg, e.span.ctxt(), "..", &mut app)
|
||||||
&format!("transmute from `{from_ty}` to `{to_ty}` which could be expressed as a pointer cast instead"),
|
.as_ty(to_ty.to_string())
|
||||||
|diag| {
|
.to_string()
|
||||||
if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) {
|
},
|
||||||
let sugg = arg.as_ty(to_ty.to_string()).to_string();
|
Some(PtrAddrCast) if !from_ty_adjusted => Sugg::hir_with_context(cx, arg, e.span.ctxt(), "..", &mut app)
|
||||||
diag.span_suggestion(e.span, "try", sugg, Applicability::MachineApplicable);
|
.as_ty(to_ty.to_string())
|
||||||
}
|
.to_string(),
|
||||||
},
|
|
||||||
);
|
// The only adjustments here would be ref-to-ptr and unsize coercions. The result of an unsize coercions can't
|
||||||
true
|
// be transmuted to a usize. For ref-to-ptr coercions, borrows need to be cast to a pointer before being cast to
|
||||||
} else {
|
// a usize.
|
||||||
false
|
Some(PtrAddrCast) => format!(
|
||||||
}
|
"{} as {to_ty}",
|
||||||
|
Sugg::hir_with_context(cx, arg, e.span.ctxt(), "..", &mut app).as_ty(from_ty)
|
||||||
|
),
|
||||||
|
_ => return false,
|
||||||
|
};
|
||||||
|
|
||||||
|
span_lint_and_sugg(
|
||||||
|
cx,
|
||||||
|
TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS,
|
||||||
|
e.span,
|
||||||
|
&format!("transmute from `{from_ty}` to `{to_ty}` which could be expressed as a pointer cast instead"),
|
||||||
|
"try",
|
||||||
|
sugg,
|
||||||
|
app,
|
||||||
|
);
|
||||||
|
true
|
||||||
}
|
}
|
||||||
|
@ -20,28 +20,16 @@ pub(super) fn is_layout_incompatible<'tcx>(cx: &LateContext<'tcx>, from: Ty<'tcx
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the type conversion can be expressed as a pointer cast, instead of
|
|
||||||
/// a transmute. In certain cases, including some invalid casts from array
|
|
||||||
/// references to pointers, this may cause additional errors to be emitted and/or
|
|
||||||
/// ICE error messages. This function will panic if that occurs.
|
|
||||||
pub(super) fn can_be_expressed_as_pointer_cast<'tcx>(
|
|
||||||
cx: &LateContext<'tcx>,
|
|
||||||
e: &'tcx Expr<'_>,
|
|
||||||
from_ty: Ty<'tcx>,
|
|
||||||
to_ty: Ty<'tcx>,
|
|
||||||
) -> bool {
|
|
||||||
use CastKind::{AddrPtrCast, ArrayPtrCast, FnPtrAddrCast, FnPtrPtrCast, PtrAddrCast, PtrPtrCast};
|
|
||||||
matches!(
|
|
||||||
check_cast(cx, e, from_ty, to_ty),
|
|
||||||
Some(PtrPtrCast | PtrAddrCast | AddrPtrCast | ArrayPtrCast | FnPtrPtrCast | FnPtrAddrCast)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If a cast from `from_ty` to `to_ty` is valid, returns an Ok containing the kind of
|
/// If a cast from `from_ty` to `to_ty` is valid, returns an Ok containing the kind of
|
||||||
/// the cast. In certain cases, including some invalid casts from array references
|
/// the cast. In certain cases, including some invalid casts from array references
|
||||||
/// to pointers, this may cause additional errors to be emitted and/or ICE error
|
/// to pointers, this may cause additional errors to be emitted and/or ICE error
|
||||||
/// messages. This function will panic if that occurs.
|
/// messages. This function will panic if that occurs.
|
||||||
fn check_cast<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> Option<CastKind> {
|
pub(super) fn check_cast<'tcx>(
|
||||||
|
cx: &LateContext<'tcx>,
|
||||||
|
e: &'tcx Expr<'_>,
|
||||||
|
from_ty: Ty<'tcx>,
|
||||||
|
to_ty: Ty<'tcx>,
|
||||||
|
) -> Option<CastKind> {
|
||||||
let hir_id = e.hir_id;
|
let hir_id = e.hir_id;
|
||||||
let local_def_id = hir_id.owner.def_id;
|
let local_def_id = hir_id.owner.def_id;
|
||||||
|
|
||||||
|
@ -263,6 +263,18 @@ fn expr_has_unnecessary_safety_comment<'tcx>(
|
|||||||
expr: &'tcx hir::Expr<'tcx>,
|
expr: &'tcx hir::Expr<'tcx>,
|
||||||
comment_pos: BytePos,
|
comment_pos: BytePos,
|
||||||
) -> Option<Span> {
|
) -> Option<Span> {
|
||||||
|
if cx.tcx.hir().parent_iter(expr.hir_id).any(|(_, ref node)| {
|
||||||
|
matches!(
|
||||||
|
node,
|
||||||
|
Node::Block(&Block {
|
||||||
|
rules: BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided),
|
||||||
|
..
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
// this should roughly be the reverse of `block_parents_have_safety_comment`
|
// this should roughly be the reverse of `block_parents_have_safety_comment`
|
||||||
if for_each_expr_with_closures(cx, expr, |expr| match expr.kind {
|
if for_each_expr_with_closures(cx, expr, |expr| match expr.kind {
|
||||||
hir::ExprKind::Block(
|
hir::ExprKind::Block(
|
||||||
|
@ -219,7 +219,8 @@ define_Conf! {
|
|||||||
///
|
///
|
||||||
/// #### Noteworthy
|
/// #### Noteworthy
|
||||||
///
|
///
|
||||||
/// A type, say `SomeType`, listed in this configuration has the same behavior of `["SomeType" , "*"], ["*", "SomeType"]` in `arithmetic_side_effects_allowed_binary`.
|
/// A type, say `SomeType`, listed in this configuration has the same behavior of
|
||||||
|
/// `["SomeType" , "*"], ["*", "SomeType"]` in `arithmetic_side_effects_allowed_binary`.
|
||||||
(arithmetic_side_effects_allowed: rustc_data_structures::fx::FxHashSet<String> = <_>::default()),
|
(arithmetic_side_effects_allowed: rustc_data_structures::fx::FxHashSet<String> = <_>::default()),
|
||||||
/// Lint: ARITHMETIC_SIDE_EFFECTS.
|
/// Lint: ARITHMETIC_SIDE_EFFECTS.
|
||||||
///
|
///
|
||||||
|
@ -14,6 +14,7 @@ use clippy_utils::diagnostics::span_lint;
|
|||||||
use clippy_utils::ty::{match_type, walk_ptrs_ty_depth};
|
use clippy_utils::ty::{match_type, walk_ptrs_ty_depth};
|
||||||
use clippy_utils::{last_path_segment, match_def_path, match_function_call, match_path, paths};
|
use clippy_utils::{last_path_segment, match_def_path, match_function_call, match_path, paths};
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
|
use itertools::Itertools;
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_hir::{
|
use rustc_hir::{
|
||||||
@ -34,8 +35,10 @@ use std::path::Path;
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
/// This is the output file of the lint collector.
|
/// This is the json output file of the lint collector.
|
||||||
const OUTPUT_FILE: &str = "../util/gh-pages/lints.json";
|
const JSON_OUTPUT_FILE: &str = "../util/gh-pages/lints.json";
|
||||||
|
/// This is the markdown output file of the lint collector.
|
||||||
|
const MARKDOWN_OUTPUT_FILE: &str = "../book/src/lint_configuration.md";
|
||||||
/// These lints are excluded from the export.
|
/// These lints are excluded from the export.
|
||||||
const BLACK_LISTED_LINTS: &[&str] = &["lint_author", "dump_hir", "internal_metadata_collector"];
|
const BLACK_LISTED_LINTS: &[&str] = &["lint_author", "dump_hir", "internal_metadata_collector"];
|
||||||
/// These groups will be ignored by the lint group matcher. This is useful for collections like
|
/// These groups will be ignored by the lint group matcher. This is useful for collections like
|
||||||
@ -176,6 +179,23 @@ This lint has the following configuration variables:
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn configs_to_markdown(&self, map_fn: fn(&ClippyConfiguration) -> String) -> String {
|
||||||
|
self.config
|
||||||
|
.iter()
|
||||||
|
.filter(|config| config.deprecation_reason.is_none())
|
||||||
|
.filter(|config| !config.lints.is_empty())
|
||||||
|
.map(map_fn)
|
||||||
|
.join("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_markdown_docs(&self) -> String {
|
||||||
|
format!(
|
||||||
|
"## Lint Configuration Options\n| <div style=\"width:290px\">Option</div> | Default Value |\n|--|--|\n{}\n\n{}\n",
|
||||||
|
self.configs_to_markdown(ClippyConfiguration::to_markdown_table_entry),
|
||||||
|
self.configs_to_markdown(ClippyConfiguration::to_markdown_paragraph),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for MetadataCollector {
|
impl Drop for MetadataCollector {
|
||||||
@ -199,12 +219,37 @@ impl Drop for MetadataCollector {
|
|||||||
|
|
||||||
collect_renames(&mut lints);
|
collect_renames(&mut lints);
|
||||||
|
|
||||||
// Outputting
|
// Outputting json
|
||||||
if Path::new(OUTPUT_FILE).exists() {
|
if Path::new(JSON_OUTPUT_FILE).exists() {
|
||||||
fs::remove_file(OUTPUT_FILE).unwrap();
|
fs::remove_file(JSON_OUTPUT_FILE).unwrap();
|
||||||
}
|
}
|
||||||
let mut file = OpenOptions::new().write(true).create(true).open(OUTPUT_FILE).unwrap();
|
let mut file = OpenOptions::new()
|
||||||
|
.write(true)
|
||||||
|
.create(true)
|
||||||
|
.open(JSON_OUTPUT_FILE)
|
||||||
|
.unwrap();
|
||||||
writeln!(file, "{}", serde_json::to_string_pretty(&lints).unwrap()).unwrap();
|
writeln!(file, "{}", serde_json::to_string_pretty(&lints).unwrap()).unwrap();
|
||||||
|
|
||||||
|
// Outputting markdown
|
||||||
|
if Path::new(MARKDOWN_OUTPUT_FILE).exists() {
|
||||||
|
fs::remove_file(MARKDOWN_OUTPUT_FILE).unwrap();
|
||||||
|
}
|
||||||
|
let mut file = OpenOptions::new()
|
||||||
|
.write(true)
|
||||||
|
.create(true)
|
||||||
|
.open(MARKDOWN_OUTPUT_FILE)
|
||||||
|
.unwrap();
|
||||||
|
writeln!(
|
||||||
|
file,
|
||||||
|
"<!--
|
||||||
|
This file is generated by `cargo collect-metadata`.
|
||||||
|
Please use that command to update the file and do not edit it by hand.
|
||||||
|
-->
|
||||||
|
|
||||||
|
{}",
|
||||||
|
self.get_markdown_docs(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,6 +550,28 @@ impl ClippyConfiguration {
|
|||||||
deprecation_reason,
|
deprecation_reason,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn to_markdown_paragraph(&self) -> String {
|
||||||
|
format!(
|
||||||
|
"### {}\n{}\n\n**Default Value:** `{}` (`{}`)\n\n{}\n\n",
|
||||||
|
self.name,
|
||||||
|
self.doc
|
||||||
|
.lines()
|
||||||
|
.map(|line| line.strip_prefix(" ").unwrap_or(line))
|
||||||
|
.join("\n"),
|
||||||
|
self.default,
|
||||||
|
self.config_type,
|
||||||
|
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})"))
|
||||||
|
.join("\n"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_markdown_table_entry(&self) -> String {
|
||||||
|
format!("| [{}](#{}) | `{}` |", self.name, self.name, self.default)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_configs() -> Vec<ClippyConfiguration> {
|
fn collect_configs() -> Vec<ClippyConfiguration> {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "clippy_utils"
|
name = "clippy_utils"
|
||||||
version = "0.1.68"
|
version = "0.1.69"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
|
@ -2491,6 +2491,10 @@ pub fn span_extract_comment(sm: &SourceMap, span: Span) -> String {
|
|||||||
comments_buf.join("\n")
|
comments_buf.join("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn span_find_starting_semi(sm: &SourceMap, span: Span) -> Span {
|
||||||
|
sm.span_take_while(span, |&ch| ch == ' ' || ch == ';')
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! op_utils {
|
macro_rules! op_utils {
|
||||||
($($name:ident $assign:ident)*) => {
|
($($name:ident $assign:ident)*) => {
|
||||||
/// Binary operation traits like `LangItem::Add`
|
/// Binary operation traits like `LangItem::Add`
|
||||||
|
@ -647,9 +647,12 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'t
|
|||||||
Some(ExprFnSig::Closure(decl, subs.as_closure().sig()))
|
Some(ExprFnSig::Closure(decl, subs.as_closure().sig()))
|
||||||
},
|
},
|
||||||
ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).subst(cx.tcx, subs), Some(id))),
|
ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).subst(cx.tcx, subs), Some(id))),
|
||||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
|
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => sig_from_bounds(
|
||||||
sig_from_bounds(cx, ty, cx.tcx.item_bounds(def_id).subst(cx.tcx, substs), cx.tcx.opt_parent(def_id))
|
cx,
|
||||||
},
|
ty,
|
||||||
|
cx.tcx.item_bounds(def_id).subst(cx.tcx, substs),
|
||||||
|
cx.tcx.opt_parent(def_id),
|
||||||
|
),
|
||||||
ty::FnPtr(sig) => Some(ExprFnSig::Sig(sig, None)),
|
ty::FnPtr(sig) => Some(ExprFnSig::Sig(sig, None)),
|
||||||
ty::Dynamic(bounds, _, _) => {
|
ty::Dynamic(bounds, _, _) => {
|
||||||
let lang_items = cx.tcx.lang_items();
|
let lang_items = cx.tcx.lang_items();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "declare_clippy_lint"
|
name = "declare_clippy_lint"
|
||||||
version = "0.1.68"
|
version = "0.1.69"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "nightly-2023-01-12"
|
channel = "nightly-2023-01-27"
|
||||||
components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
|
components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
|
||||||
|
@ -28,7 +28,7 @@ with:
|
|||||||
-D --deny OPT Set lint denied
|
-D --deny OPT Set lint denied
|
||||||
-F --forbid OPT Set lint forbidden
|
-F --forbid OPT Set lint forbidden
|
||||||
|
|
||||||
You can use tool lints to allow or deny lints from your code, eg.:
|
You can use tool lints to allow or deny lints from your code, e.g.:
|
||||||
|
|
||||||
#[allow(clippy::needless_lifetimes)]
|
#[allow(clippy::needless_lifetimes)]
|
||||||
"#;
|
"#;
|
||||||
|
@ -7,14 +7,6 @@ LL | const DEREF_TRAIT: [&str; 4] = ["core", "ops", "deref", "Deref"];
|
|||||||
= help: convert all references to use `sym::Deref`
|
= help: convert all references to use `sym::Deref`
|
||||||
= note: `-D clippy::unnecessary-def-path` implied by `-D warnings`
|
= note: `-D clippy::unnecessary-def-path` implied by `-D warnings`
|
||||||
|
|
||||||
error: hardcoded path to a language item
|
|
||||||
--> $DIR/unnecessary_def_path_hardcoded_path.rs:11:40
|
|
||||||
|
|
|
||||||
LL | const DEREF_MUT_TRAIT: [&str; 4] = ["core", "ops", "deref", "DerefMut"];
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= help: convert all references to use `LangItem::DerefMut`
|
|
||||||
|
|
||||||
error: hardcoded path to a diagnostic item
|
error: hardcoded path to a diagnostic item
|
||||||
--> $DIR/unnecessary_def_path_hardcoded_path.rs:12:43
|
--> $DIR/unnecessary_def_path_hardcoded_path.rs:12:43
|
||||||
|
|
|
|
||||||
@ -23,5 +15,13 @@ LL | const DEREF_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "Deref",
|
|||||||
|
|
|
|
||||||
= help: convert all references to use `sym::deref_method`
|
= help: convert all references to use `sym::deref_method`
|
||||||
|
|
||||||
|
error: hardcoded path to a language item
|
||||||
|
--> $DIR/unnecessary_def_path_hardcoded_path.rs:11:40
|
||||||
|
|
|
||||||
|
LL | const DEREF_MUT_TRAIT: [&str; 4] = ["core", "ops", "deref", "DerefMut"];
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: convert all references to use `LangItem::DerefMut`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
161
src/tools/clippy/tests/ui/bool_assert_comparison.fixed
Normal file
161
src/tools/clippy/tests/ui/bool_assert_comparison.fixed
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
#![allow(unused, clippy::assertions_on_constants)]
|
||||||
|
#![warn(clippy::bool_assert_comparison)]
|
||||||
|
|
||||||
|
use std::ops::Not;
|
||||||
|
|
||||||
|
macro_rules! a {
|
||||||
|
() => {
|
||||||
|
true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
macro_rules! b {
|
||||||
|
() => {
|
||||||
|
true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements the Not trait but with an output type
|
||||||
|
// that's not bool. Should not suggest a rewrite
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
enum ImplNotTraitWithoutBool {
|
||||||
|
VariantX(bool),
|
||||||
|
VariantY(u32),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq<bool> for ImplNotTraitWithoutBool {
|
||||||
|
fn eq(&self, other: &bool) -> bool {
|
||||||
|
match *self {
|
||||||
|
ImplNotTraitWithoutBool::VariantX(b) => b == *other,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Not for ImplNotTraitWithoutBool {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn not(self) -> Self::Output {
|
||||||
|
match self {
|
||||||
|
ImplNotTraitWithoutBool::VariantX(b) => ImplNotTraitWithoutBool::VariantX(!b),
|
||||||
|
ImplNotTraitWithoutBool::VariantY(0) => ImplNotTraitWithoutBool::VariantY(1),
|
||||||
|
ImplNotTraitWithoutBool::VariantY(_) => ImplNotTraitWithoutBool::VariantY(0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This type implements the Not trait with an Output of
|
||||||
|
// type bool. Using assert!(..) must be suggested
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
struct ImplNotTraitWithBool;
|
||||||
|
|
||||||
|
impl PartialEq<bool> for ImplNotTraitWithBool {
|
||||||
|
fn eq(&self, other: &bool) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Not for ImplNotTraitWithBool {
|
||||||
|
type Output = bool;
|
||||||
|
|
||||||
|
fn not(self) -> Self::Output {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct NonCopy;
|
||||||
|
|
||||||
|
impl PartialEq<bool> for NonCopy {
|
||||||
|
fn eq(&self, other: &bool) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Not for NonCopy {
|
||||||
|
type Output = bool;
|
||||||
|
|
||||||
|
fn not(self) -> Self::Output {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let a = ImplNotTraitWithoutBool::VariantX(true);
|
||||||
|
let b = ImplNotTraitWithBool;
|
||||||
|
|
||||||
|
assert_eq!("a".len(), 1);
|
||||||
|
assert!("a".is_empty());
|
||||||
|
assert!("".is_empty());
|
||||||
|
assert!("".is_empty());
|
||||||
|
assert_eq!(a!(), b!());
|
||||||
|
assert_eq!(a!(), "".is_empty());
|
||||||
|
assert_eq!("".is_empty(), b!());
|
||||||
|
assert_eq!(a, true);
|
||||||
|
assert!(b);
|
||||||
|
|
||||||
|
assert_ne!("a".len(), 1);
|
||||||
|
assert!("a".is_empty());
|
||||||
|
assert!("".is_empty());
|
||||||
|
assert!("".is_empty());
|
||||||
|
assert_ne!(a!(), b!());
|
||||||
|
assert_ne!(a!(), "".is_empty());
|
||||||
|
assert_ne!("".is_empty(), b!());
|
||||||
|
assert_ne!(a, true);
|
||||||
|
assert!(b);
|
||||||
|
|
||||||
|
debug_assert_eq!("a".len(), 1);
|
||||||
|
debug_assert!("a".is_empty());
|
||||||
|
debug_assert!("".is_empty());
|
||||||
|
debug_assert!("".is_empty());
|
||||||
|
debug_assert_eq!(a!(), b!());
|
||||||
|
debug_assert_eq!(a!(), "".is_empty());
|
||||||
|
debug_assert_eq!("".is_empty(), b!());
|
||||||
|
debug_assert_eq!(a, true);
|
||||||
|
debug_assert!(b);
|
||||||
|
|
||||||
|
debug_assert_ne!("a".len(), 1);
|
||||||
|
debug_assert!("a".is_empty());
|
||||||
|
debug_assert!("".is_empty());
|
||||||
|
debug_assert!("".is_empty());
|
||||||
|
debug_assert_ne!(a!(), b!());
|
||||||
|
debug_assert_ne!(a!(), "".is_empty());
|
||||||
|
debug_assert_ne!("".is_empty(), b!());
|
||||||
|
debug_assert_ne!(a, true);
|
||||||
|
debug_assert!(b);
|
||||||
|
|
||||||
|
// assert with error messages
|
||||||
|
assert_eq!("a".len(), 1, "tadam {}", 1);
|
||||||
|
assert_eq!("a".len(), 1, "tadam {}", true);
|
||||||
|
assert!("a".is_empty(), "tadam {}", 1);
|
||||||
|
assert!("a".is_empty(), "tadam {}", true);
|
||||||
|
assert!("a".is_empty(), "tadam {}", true);
|
||||||
|
assert_eq!(a, true, "tadam {}", false);
|
||||||
|
|
||||||
|
debug_assert_eq!("a".len(), 1, "tadam {}", 1);
|
||||||
|
debug_assert_eq!("a".len(), 1, "tadam {}", true);
|
||||||
|
debug_assert!("a".is_empty(), "tadam {}", 1);
|
||||||
|
debug_assert!("a".is_empty(), "tadam {}", true);
|
||||||
|
debug_assert!("a".is_empty(), "tadam {}", true);
|
||||||
|
debug_assert_eq!(a, true, "tadam {}", false);
|
||||||
|
|
||||||
|
assert!(a!());
|
||||||
|
assert!(b!());
|
||||||
|
|
||||||
|
use debug_assert_eq as renamed;
|
||||||
|
renamed!(a, true);
|
||||||
|
debug_assert!(b);
|
||||||
|
|
||||||
|
let non_copy = NonCopy;
|
||||||
|
assert_eq!(non_copy, true);
|
||||||
|
// changing the above to `assert!(non_copy)` would cause a `borrow of moved value`
|
||||||
|
println!("{non_copy:?}");
|
||||||
|
|
||||||
|
macro_rules! in_macro {
|
||||||
|
($v:expr) => {{
|
||||||
|
assert_eq!($v, true);
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
in_macro!(a);
|
||||||
|
}
|
@ -1,3 +1,6 @@
|
|||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
#![allow(unused, clippy::assertions_on_constants)]
|
||||||
#![warn(clippy::bool_assert_comparison)]
|
#![warn(clippy::bool_assert_comparison)]
|
||||||
|
|
||||||
use std::ops::Not;
|
use std::ops::Not;
|
||||||
@ -15,7 +18,7 @@ macro_rules! b {
|
|||||||
|
|
||||||
// Implements the Not trait but with an output type
|
// Implements the Not trait but with an output type
|
||||||
// that's not bool. Should not suggest a rewrite
|
// that's not bool. Should not suggest a rewrite
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
enum ImplNotTraitWithoutBool {
|
enum ImplNotTraitWithoutBool {
|
||||||
VariantX(bool),
|
VariantX(bool),
|
||||||
VariantY(u32),
|
VariantY(u32),
|
||||||
@ -44,7 +47,7 @@ impl Not for ImplNotTraitWithoutBool {
|
|||||||
|
|
||||||
// This type implements the Not trait with an Output of
|
// This type implements the Not trait with an Output of
|
||||||
// type bool. Using assert!(..) must be suggested
|
// type bool. Using assert!(..) must be suggested
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
struct ImplNotTraitWithBool;
|
struct ImplNotTraitWithBool;
|
||||||
|
|
||||||
impl PartialEq<bool> for ImplNotTraitWithBool {
|
impl PartialEq<bool> for ImplNotTraitWithBool {
|
||||||
@ -61,6 +64,23 @@ impl Not for ImplNotTraitWithBool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct NonCopy;
|
||||||
|
|
||||||
|
impl PartialEq<bool> for NonCopy {
|
||||||
|
fn eq(&self, other: &bool) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Not for NonCopy {
|
||||||
|
type Output = bool;
|
||||||
|
|
||||||
|
fn not(self) -> Self::Output {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let a = ImplNotTraitWithoutBool::VariantX(true);
|
let a = ImplNotTraitWithoutBool::VariantX(true);
|
||||||
let b = ImplNotTraitWithBool;
|
let b = ImplNotTraitWithBool;
|
||||||
@ -119,4 +139,23 @@ fn main() {
|
|||||||
debug_assert_eq!("a".is_empty(), false, "tadam {}", true);
|
debug_assert_eq!("a".is_empty(), false, "tadam {}", true);
|
||||||
debug_assert_eq!(false, "a".is_empty(), "tadam {}", true);
|
debug_assert_eq!(false, "a".is_empty(), "tadam {}", true);
|
||||||
debug_assert_eq!(a, true, "tadam {}", false);
|
debug_assert_eq!(a, true, "tadam {}", false);
|
||||||
|
|
||||||
|
assert_eq!(a!(), true);
|
||||||
|
assert_eq!(true, b!());
|
||||||
|
|
||||||
|
use debug_assert_eq as renamed;
|
||||||
|
renamed!(a, true);
|
||||||
|
renamed!(b, true);
|
||||||
|
|
||||||
|
let non_copy = NonCopy;
|
||||||
|
assert_eq!(non_copy, true);
|
||||||
|
// changing the above to `assert!(non_copy)` would cause a `borrow of moved value`
|
||||||
|
println!("{non_copy:?}");
|
||||||
|
|
||||||
|
macro_rules! in_macro {
|
||||||
|
($v:expr) => {{
|
||||||
|
assert_eq!($v, true);
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
in_macro!(a);
|
||||||
}
|
}
|
||||||
|
@ -1,136 +1,303 @@
|
|||||||
error: used `assert_eq!` with a literal bool
|
error: used `assert_eq!` with a literal bool
|
||||||
--> $DIR/bool_assert_comparison.rs:69:5
|
|
||||||
|
|
|
||||||
LL | assert_eq!("a".is_empty(), false);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `assert!(..)`
|
|
||||||
|
|
|
||||||
= note: `-D clippy::bool-assert-comparison` implied by `-D warnings`
|
|
||||||
|
|
||||||
error: used `assert_eq!` with a literal bool
|
|
||||||
--> $DIR/bool_assert_comparison.rs:70:5
|
|
||||||
|
|
|
||||||
LL | assert_eq!("".is_empty(), true);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `assert!(..)`
|
|
||||||
|
|
||||||
error: used `assert_eq!` with a literal bool
|
|
||||||
--> $DIR/bool_assert_comparison.rs:71:5
|
|
||||||
|
|
|
||||||
LL | assert_eq!(true, "".is_empty());
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `assert!(..)`
|
|
||||||
|
|
||||||
error: used `assert_eq!` with a literal bool
|
|
||||||
--> $DIR/bool_assert_comparison.rs:76:5
|
|
||||||
|
|
|
||||||
LL | assert_eq!(b, true);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^ help: replace it with: `assert!(..)`
|
|
||||||
|
|
||||||
error: used `assert_ne!` with a literal bool
|
|
||||||
--> $DIR/bool_assert_comparison.rs:79:5
|
|
||||||
|
|
|
||||||
LL | assert_ne!("a".is_empty(), false);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `assert!(..)`
|
|
||||||
|
|
||||||
error: used `assert_ne!` with a literal bool
|
|
||||||
--> $DIR/bool_assert_comparison.rs:80:5
|
|
||||||
|
|
|
||||||
LL | assert_ne!("".is_empty(), true);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `assert!(..)`
|
|
||||||
|
|
||||||
error: used `assert_ne!` with a literal bool
|
|
||||||
--> $DIR/bool_assert_comparison.rs:81:5
|
|
||||||
|
|
|
||||||
LL | assert_ne!(true, "".is_empty());
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `assert!(..)`
|
|
||||||
|
|
||||||
error: used `assert_ne!` with a literal bool
|
|
||||||
--> $DIR/bool_assert_comparison.rs:86:5
|
|
||||||
|
|
|
||||||
LL | assert_ne!(b, true);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^ help: replace it with: `assert!(..)`
|
|
||||||
|
|
||||||
error: used `debug_assert_eq!` with a literal bool
|
|
||||||
--> $DIR/bool_assert_comparison.rs:89:5
|
--> $DIR/bool_assert_comparison.rs:89:5
|
||||||
|
|
|
|
||||||
LL | debug_assert_eq!("a".is_empty(), false);
|
LL | assert_eq!("a".is_empty(), false);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `debug_assert!(..)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `-D clippy::bool-assert-comparison` implied by `-D warnings`
|
||||||
|
help: replace it with `assert!(..)`
|
||||||
|
|
|
||||||
|
LL - assert_eq!("a".is_empty(), false);
|
||||||
|
LL + assert!("a".is_empty());
|
||||||
|
|
|
||||||
|
|
||||||
error: used `debug_assert_eq!` with a literal bool
|
error: used `assert_eq!` with a literal bool
|
||||||
--> $DIR/bool_assert_comparison.rs:90:5
|
--> $DIR/bool_assert_comparison.rs:90:5
|
||||||
|
|
|
|
||||||
LL | debug_assert_eq!("".is_empty(), true);
|
LL | assert_eq!("".is_empty(), true);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `debug_assert!(..)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `assert!(..)`
|
||||||
|
|
|
||||||
|
LL - assert_eq!("".is_empty(), true);
|
||||||
|
LL + assert!("".is_empty());
|
||||||
|
|
|
||||||
|
|
||||||
error: used `debug_assert_eq!` with a literal bool
|
error: used `assert_eq!` with a literal bool
|
||||||
--> $DIR/bool_assert_comparison.rs:91:5
|
--> $DIR/bool_assert_comparison.rs:91:5
|
||||||
|
|
|
|
||||||
LL | debug_assert_eq!(true, "".is_empty());
|
LL | assert_eq!(true, "".is_empty());
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `debug_assert!(..)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `assert!(..)`
|
||||||
|
|
|
||||||
|
LL - assert_eq!(true, "".is_empty());
|
||||||
|
LL + assert!("".is_empty());
|
||||||
|
|
|
||||||
|
|
||||||
error: used `debug_assert_eq!` with a literal bool
|
error: used `assert_eq!` with a literal bool
|
||||||
--> $DIR/bool_assert_comparison.rs:96:5
|
--> $DIR/bool_assert_comparison.rs:96:5
|
||||||
|
|
|
|
||||||
LL | debug_assert_eq!(b, true);
|
LL | assert_eq!(b, true);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `debug_assert!(..)`
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `assert!(..)`
|
||||||
|
|
|
||||||
|
LL - assert_eq!(b, true);
|
||||||
|
LL + assert!(b);
|
||||||
|
|
|
||||||
|
|
||||||
error: used `debug_assert_ne!` with a literal bool
|
error: used `assert_ne!` with a literal bool
|
||||||
--> $DIR/bool_assert_comparison.rs:99:5
|
--> $DIR/bool_assert_comparison.rs:99:5
|
||||||
|
|
|
|
||||||
LL | debug_assert_ne!("a".is_empty(), false);
|
LL | assert_ne!("a".is_empty(), false);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `debug_assert!(..)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `assert!(..)`
|
||||||
|
|
|
||||||
|
LL - assert_ne!("a".is_empty(), false);
|
||||||
|
LL + assert!("a".is_empty());
|
||||||
|
|
|
||||||
|
|
||||||
error: used `debug_assert_ne!` with a literal bool
|
error: used `assert_ne!` with a literal bool
|
||||||
--> $DIR/bool_assert_comparison.rs:100:5
|
--> $DIR/bool_assert_comparison.rs:100:5
|
||||||
|
|
|
|
||||||
LL | debug_assert_ne!("".is_empty(), true);
|
LL | assert_ne!("".is_empty(), true);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `debug_assert!(..)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `assert!(..)`
|
||||||
|
|
|
||||||
|
LL - assert_ne!("".is_empty(), true);
|
||||||
|
LL + assert!("".is_empty());
|
||||||
|
|
|
||||||
|
|
||||||
error: used `debug_assert_ne!` with a literal bool
|
error: used `assert_ne!` with a literal bool
|
||||||
--> $DIR/bool_assert_comparison.rs:101:5
|
--> $DIR/bool_assert_comparison.rs:101:5
|
||||||
|
|
|
|
||||||
LL | debug_assert_ne!(true, "".is_empty());
|
LL | assert_ne!(true, "".is_empty());
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `debug_assert!(..)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `assert!(..)`
|
||||||
|
|
|
||||||
|
LL - assert_ne!(true, "".is_empty());
|
||||||
|
LL + assert!("".is_empty());
|
||||||
|
|
|
||||||
|
|
||||||
error: used `debug_assert_ne!` with a literal bool
|
error: used `assert_ne!` with a literal bool
|
||||||
--> $DIR/bool_assert_comparison.rs:106:5
|
--> $DIR/bool_assert_comparison.rs:106:5
|
||||||
|
|
|
|
||||||
LL | debug_assert_ne!(b, true);
|
LL | assert_ne!(b, true);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `debug_assert!(..)`
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `assert!(..)`
|
||||||
|
|
|
||||||
|
LL - assert_ne!(b, true);
|
||||||
|
LL + assert!(b);
|
||||||
|
|
|
||||||
|
|
||||||
error: used `assert_eq!` with a literal bool
|
error: used `debug_assert_eq!` with a literal bool
|
||||||
|
--> $DIR/bool_assert_comparison.rs:109:5
|
||||||
|
|
|
||||||
|
LL | debug_assert_eq!("a".is_empty(), false);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `debug_assert!(..)`
|
||||||
|
|
|
||||||
|
LL - debug_assert_eq!("a".is_empty(), false);
|
||||||
|
LL + debug_assert!("a".is_empty());
|
||||||
|
|
|
||||||
|
|
||||||
|
error: used `debug_assert_eq!` with a literal bool
|
||||||
|
--> $DIR/bool_assert_comparison.rs:110:5
|
||||||
|
|
|
||||||
|
LL | debug_assert_eq!("".is_empty(), true);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `debug_assert!(..)`
|
||||||
|
|
|
||||||
|
LL - debug_assert_eq!("".is_empty(), true);
|
||||||
|
LL + debug_assert!("".is_empty());
|
||||||
|
|
|
||||||
|
|
||||||
|
error: used `debug_assert_eq!` with a literal bool
|
||||||
--> $DIR/bool_assert_comparison.rs:111:5
|
--> $DIR/bool_assert_comparison.rs:111:5
|
||||||
|
|
|
|
||||||
LL | assert_eq!("a".is_empty(), false, "tadam {}", 1);
|
LL | debug_assert_eq!(true, "".is_empty());
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `assert!(..)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: used `assert_eq!` with a literal bool
|
|
||||||
--> $DIR/bool_assert_comparison.rs:112:5
|
|
||||||
|
|
|
|
||||||
LL | assert_eq!("a".is_empty(), false, "tadam {}", true);
|
help: replace it with `debug_assert!(..)`
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `assert!(..)`
|
|
|
||||||
|
LL - debug_assert_eq!(true, "".is_empty());
|
||||||
error: used `assert_eq!` with a literal bool
|
LL + debug_assert!("".is_empty());
|
||||||
--> $DIR/bool_assert_comparison.rs:113:5
|
|
||||||
|
|
|
|
||||||
LL | assert_eq!(false, "a".is_empty(), "tadam {}", true);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `assert!(..)`
|
|
||||||
|
|
||||||
error: used `debug_assert_eq!` with a literal bool
|
error: used `debug_assert_eq!` with a literal bool
|
||||||
--> $DIR/bool_assert_comparison.rs:118:5
|
--> $DIR/bool_assert_comparison.rs:116:5
|
||||||
|
|
|
||||||
|
LL | debug_assert_eq!(b, true);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `debug_assert!(..)`
|
||||||
|
|
|
||||||
|
LL - debug_assert_eq!(b, true);
|
||||||
|
LL + debug_assert!(b);
|
||||||
|
|
|
|
||||||
LL | debug_assert_eq!("a".is_empty(), false, "tadam {}", 1);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `debug_assert!(..)`
|
|
||||||
|
|
||||||
error: used `debug_assert_eq!` with a literal bool
|
error: used `debug_assert_ne!` with a literal bool
|
||||||
--> $DIR/bool_assert_comparison.rs:119:5
|
--> $DIR/bool_assert_comparison.rs:119:5
|
||||||
|
|
|
|
||||||
LL | debug_assert_eq!("a".is_empty(), false, "tadam {}", true);
|
LL | debug_assert_ne!("a".is_empty(), false);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `debug_assert!(..)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `debug_assert!(..)`
|
||||||
|
|
|
||||||
|
LL - debug_assert_ne!("a".is_empty(), false);
|
||||||
|
LL + debug_assert!("a".is_empty());
|
||||||
|
|
|
||||||
|
|
||||||
error: used `debug_assert_eq!` with a literal bool
|
error: used `debug_assert_ne!` with a literal bool
|
||||||
--> $DIR/bool_assert_comparison.rs:120:5
|
--> $DIR/bool_assert_comparison.rs:120:5
|
||||||
|
|
|
|
||||||
|
LL | debug_assert_ne!("".is_empty(), true);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `debug_assert!(..)`
|
||||||
|
|
|
||||||
|
LL - debug_assert_ne!("".is_empty(), true);
|
||||||
|
LL + debug_assert!("".is_empty());
|
||||||
|
|
|
||||||
|
|
||||||
|
error: used `debug_assert_ne!` with a literal bool
|
||||||
|
--> $DIR/bool_assert_comparison.rs:121:5
|
||||||
|
|
|
||||||
|
LL | debug_assert_ne!(true, "".is_empty());
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `debug_assert!(..)`
|
||||||
|
|
|
||||||
|
LL - debug_assert_ne!(true, "".is_empty());
|
||||||
|
LL + debug_assert!("".is_empty());
|
||||||
|
|
|
||||||
|
|
||||||
|
error: used `debug_assert_ne!` with a literal bool
|
||||||
|
--> $DIR/bool_assert_comparison.rs:126:5
|
||||||
|
|
|
||||||
|
LL | debug_assert_ne!(b, true);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `debug_assert!(..)`
|
||||||
|
|
|
||||||
|
LL - debug_assert_ne!(b, true);
|
||||||
|
LL + debug_assert!(b);
|
||||||
|
|
|
||||||
|
|
||||||
|
error: used `assert_eq!` with a literal bool
|
||||||
|
--> $DIR/bool_assert_comparison.rs:131:5
|
||||||
|
|
|
||||||
|
LL | assert_eq!("a".is_empty(), false, "tadam {}", 1);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `assert!(..)`
|
||||||
|
|
|
||||||
|
LL - assert_eq!("a".is_empty(), false, "tadam {}", 1);
|
||||||
|
LL + assert!("a".is_empty(), "tadam {}", 1);
|
||||||
|
|
|
||||||
|
|
||||||
|
error: used `assert_eq!` with a literal bool
|
||||||
|
--> $DIR/bool_assert_comparison.rs:132:5
|
||||||
|
|
|
||||||
|
LL | assert_eq!("a".is_empty(), false, "tadam {}", true);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `assert!(..)`
|
||||||
|
|
|
||||||
|
LL - assert_eq!("a".is_empty(), false, "tadam {}", true);
|
||||||
|
LL + assert!("a".is_empty(), "tadam {}", true);
|
||||||
|
|
|
||||||
|
|
||||||
|
error: used `assert_eq!` with a literal bool
|
||||||
|
--> $DIR/bool_assert_comparison.rs:133:5
|
||||||
|
|
|
||||||
|
LL | assert_eq!(false, "a".is_empty(), "tadam {}", true);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `assert!(..)`
|
||||||
|
|
|
||||||
|
LL - assert_eq!(false, "a".is_empty(), "tadam {}", true);
|
||||||
|
LL + assert!("a".is_empty(), "tadam {}", true);
|
||||||
|
|
|
||||||
|
|
||||||
|
error: used `debug_assert_eq!` with a literal bool
|
||||||
|
--> $DIR/bool_assert_comparison.rs:138:5
|
||||||
|
|
|
||||||
|
LL | debug_assert_eq!("a".is_empty(), false, "tadam {}", 1);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `debug_assert!(..)`
|
||||||
|
|
|
||||||
|
LL - debug_assert_eq!("a".is_empty(), false, "tadam {}", 1);
|
||||||
|
LL + debug_assert!("a".is_empty(), "tadam {}", 1);
|
||||||
|
|
|
||||||
|
|
||||||
|
error: used `debug_assert_eq!` with a literal bool
|
||||||
|
--> $DIR/bool_assert_comparison.rs:139:5
|
||||||
|
|
|
||||||
|
LL | debug_assert_eq!("a".is_empty(), false, "tadam {}", true);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `debug_assert!(..)`
|
||||||
|
|
|
||||||
|
LL - debug_assert_eq!("a".is_empty(), false, "tadam {}", true);
|
||||||
|
LL + debug_assert!("a".is_empty(), "tadam {}", true);
|
||||||
|
|
|
||||||
|
|
||||||
|
error: used `debug_assert_eq!` with a literal bool
|
||||||
|
--> $DIR/bool_assert_comparison.rs:140:5
|
||||||
|
|
|
||||||
LL | debug_assert_eq!(false, "a".is_empty(), "tadam {}", true);
|
LL | debug_assert_eq!(false, "a".is_empty(), "tadam {}", true);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `debug_assert!(..)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `debug_assert!(..)`
|
||||||
|
|
|
||||||
|
LL - debug_assert_eq!(false, "a".is_empty(), "tadam {}", true);
|
||||||
|
LL + debug_assert!("a".is_empty(), "tadam {}", true);
|
||||||
|
|
|
||||||
|
|
||||||
error: aborting due to 22 previous errors
|
error: used `assert_eq!` with a literal bool
|
||||||
|
--> $DIR/bool_assert_comparison.rs:143:5
|
||||||
|
|
|
||||||
|
LL | assert_eq!(a!(), true);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `assert!(..)`
|
||||||
|
|
|
||||||
|
LL - assert_eq!(a!(), true);
|
||||||
|
LL + assert!(a!());
|
||||||
|
|
|
||||||
|
|
||||||
|
error: used `assert_eq!` with a literal bool
|
||||||
|
--> $DIR/bool_assert_comparison.rs:144:5
|
||||||
|
|
|
||||||
|
LL | assert_eq!(true, b!());
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `assert!(..)`
|
||||||
|
|
|
||||||
|
LL - assert_eq!(true, b!());
|
||||||
|
LL + assert!(b!());
|
||||||
|
|
|
||||||
|
|
||||||
|
error: used `debug_assert_eq!` with a literal bool
|
||||||
|
--> $DIR/bool_assert_comparison.rs:148:5
|
||||||
|
|
|
||||||
|
LL | renamed!(b, true);
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: replace it with `debug_assert!(..)`
|
||||||
|
|
|
||||||
|
LL - renamed!(b, true);
|
||||||
|
LL + debug_assert!(b);
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 25 previous errors
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ fn main() {
|
|||||||
1i32 as u8;
|
1i32 as u8;
|
||||||
1f64 as isize;
|
1f64 as isize;
|
||||||
1f64 as usize;
|
1f64 as usize;
|
||||||
|
1f32 as u32 as u16;
|
||||||
// Test clippy::cast_possible_wrap
|
// Test clippy::cast_possible_wrap
|
||||||
1u8 as i8;
|
1u8 as i8;
|
||||||
1u16 as i16;
|
1u16 as i16;
|
||||||
|
@ -42,13 +42,24 @@ error: casting `f32` to `i32` may truncate the value
|
|||||||
LL | 1f32 as i32;
|
LL | 1f32 as i32;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
= note: `-D clippy::cast-possible-truncation` implied by `-D warnings`
|
= note: `-D clippy::cast-possible-truncation` implied by `-D warnings`
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | i32::try_from(1f32);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `f32` to `u32` may truncate the value
|
error: casting `f32` to `u32` may truncate the value
|
||||||
--> $DIR/cast.rs:25:5
|
--> $DIR/cast.rs:25:5
|
||||||
|
|
|
|
||||||
LL | 1f32 as u32;
|
LL | 1f32 as u32;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | u32::try_from(1f32);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `f32` to `u32` may lose the sign of the value
|
error: casting `f32` to `u32` may lose the sign of the value
|
||||||
--> $DIR/cast.rs:25:5
|
--> $DIR/cast.rs:25:5
|
||||||
@ -63,30 +74,60 @@ error: casting `f64` to `f32` may truncate the value
|
|||||||
|
|
|
|
||||||
LL | 1f64 as f32;
|
LL | 1f64 as f32;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | f32::try_from(1f64);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `i32` to `i8` may truncate the value
|
error: casting `i32` to `i8` may truncate the value
|
||||||
--> $DIR/cast.rs:27:5
|
--> $DIR/cast.rs:27:5
|
||||||
|
|
|
|
||||||
LL | 1i32 as i8;
|
LL | 1i32 as i8;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | i8::try_from(1i32);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `i32` to `u8` may truncate the value
|
error: casting `i32` to `u8` may truncate the value
|
||||||
--> $DIR/cast.rs:28:5
|
--> $DIR/cast.rs:28:5
|
||||||
|
|
|
|
||||||
LL | 1i32 as u8;
|
LL | 1i32 as u8;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | u8::try_from(1i32);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `f64` to `isize` may truncate the value
|
error: casting `f64` to `isize` may truncate the value
|
||||||
--> $DIR/cast.rs:29:5
|
--> $DIR/cast.rs:29:5
|
||||||
|
|
|
|
||||||
LL | 1f64 as isize;
|
LL | 1f64 as isize;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | isize::try_from(1f64);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `f64` to `usize` may truncate the value
|
error: casting `f64` to `usize` may truncate the value
|
||||||
--> $DIR/cast.rs:30:5
|
--> $DIR/cast.rs:30:5
|
||||||
|
|
|
|
||||||
LL | 1f64 as usize;
|
LL | 1f64 as usize;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | usize::try_from(1f64);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `f64` to `usize` may lose the sign of the value
|
error: casting `f64` to `usize` may lose the sign of the value
|
||||||
--> $DIR/cast.rs:30:5
|
--> $DIR/cast.rs:30:5
|
||||||
@ -94,8 +135,38 @@ error: casting `f64` to `usize` may lose the sign of the value
|
|||||||
LL | 1f64 as usize;
|
LL | 1f64 as usize;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: casting `u32` to `u16` may truncate the value
|
||||||
|
--> $DIR/cast.rs:31:5
|
||||||
|
|
|
||||||
|
LL | 1f32 as u32 as u16;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | u16::try_from(1f32 as u32);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
error: casting `f32` to `u32` may truncate the value
|
||||||
|
--> $DIR/cast.rs:31:5
|
||||||
|
|
|
||||||
|
LL | 1f32 as u32 as u16;
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | u32::try_from(1f32) as u16;
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
error: casting `f32` to `u32` may lose the sign of the value
|
||||||
|
--> $DIR/cast.rs:31:5
|
||||||
|
|
|
||||||
|
LL | 1f32 as u32 as u16;
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
error: casting `u8` to `i8` may wrap around the value
|
error: casting `u8` to `i8` may wrap around the value
|
||||||
--> $DIR/cast.rs:32:5
|
--> $DIR/cast.rs:33:5
|
||||||
|
|
|
|
||||||
LL | 1u8 as i8;
|
LL | 1u8 as i8;
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
@ -103,61 +174,79 @@ LL | 1u8 as i8;
|
|||||||
= note: `-D clippy::cast-possible-wrap` implied by `-D warnings`
|
= note: `-D clippy::cast-possible-wrap` implied by `-D warnings`
|
||||||
|
|
||||||
error: casting `u16` to `i16` may wrap around the value
|
error: casting `u16` to `i16` may wrap around the value
|
||||||
--> $DIR/cast.rs:33:5
|
--> $DIR/cast.rs:34:5
|
||||||
|
|
|
|
||||||
LL | 1u16 as i16;
|
LL | 1u16 as i16;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
error: casting `u32` to `i32` may wrap around the value
|
error: casting `u32` to `i32` may wrap around the value
|
||||||
--> $DIR/cast.rs:34:5
|
--> $DIR/cast.rs:35:5
|
||||||
|
|
|
|
||||||
LL | 1u32 as i32;
|
LL | 1u32 as i32;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
error: casting `u64` to `i64` may wrap around the value
|
error: casting `u64` to `i64` may wrap around the value
|
||||||
--> $DIR/cast.rs:35:5
|
--> $DIR/cast.rs:36:5
|
||||||
|
|
|
|
||||||
LL | 1u64 as i64;
|
LL | 1u64 as i64;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
error: casting `usize` to `isize` may wrap around the value
|
error: casting `usize` to `isize` may wrap around the value
|
||||||
--> $DIR/cast.rs:36:5
|
--> $DIR/cast.rs:37:5
|
||||||
|
|
|
|
||||||
LL | 1usize as isize;
|
LL | 1usize as isize;
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: casting `i32` to `u32` may lose the sign of the value
|
error: casting `i32` to `u32` may lose the sign of the value
|
||||||
--> $DIR/cast.rs:39:5
|
--> $DIR/cast.rs:40:5
|
||||||
|
|
|
|
||||||
LL | -1i32 as u32;
|
LL | -1i32 as u32;
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
error: casting `isize` to `usize` may lose the sign of the value
|
error: casting `isize` to `usize` may lose the sign of the value
|
||||||
--> $DIR/cast.rs:41:5
|
--> $DIR/cast.rs:42:5
|
||||||
|
|
|
|
||||||
LL | -1isize as usize;
|
LL | -1isize as usize;
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: casting `i64` to `i8` may truncate the value
|
error: casting `i64` to `i8` may truncate the value
|
||||||
--> $DIR/cast.rs:108:5
|
--> $DIR/cast.rs:109:5
|
||||||
|
|
|
|
||||||
LL | (-99999999999i64).min(1) as i8; // should be linted because signed
|
LL | (-99999999999i64).min(1) as i8; // should be linted because signed
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | i8::try_from((-99999999999i64).min(1)); // should be linted because signed
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `u64` to `u8` may truncate the value
|
error: casting `u64` to `u8` may truncate the value
|
||||||
--> $DIR/cast.rs:120:5
|
--> $DIR/cast.rs:121:5
|
||||||
|
|
|
|
||||||
LL | 999999u64.clamp(0, 256) as u8; // should still be linted
|
LL | 999999u64.clamp(0, 256) as u8; // should still be linted
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | u8::try_from(999999u64.clamp(0, 256)); // should still be linted
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `main::E2` to `u8` may truncate the value
|
error: casting `main::E2` to `u8` may truncate the value
|
||||||
--> $DIR/cast.rs:141:21
|
--> $DIR/cast.rs:142:21
|
||||||
|
|
|
|
||||||
LL | let _ = self as u8;
|
LL | let _ = self as u8;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | let _ = u8::try_from(self);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `main::E2::B` to `u8` will truncate the value
|
error: casting `main::E2::B` to `u8` will truncate the value
|
||||||
--> $DIR/cast.rs:142:21
|
--> $DIR/cast.rs:143:21
|
||||||
|
|
|
|
||||||
LL | let _ = Self::B as u8;
|
LL | let _ = Self::B as u8;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
@ -165,46 +254,82 @@ LL | let _ = Self::B as u8;
|
|||||||
= note: `-D clippy::cast-enum-truncation` implied by `-D warnings`
|
= note: `-D clippy::cast-enum-truncation` implied by `-D warnings`
|
||||||
|
|
||||||
error: casting `main::E5` to `i8` may truncate the value
|
error: casting `main::E5` to `i8` may truncate the value
|
||||||
--> $DIR/cast.rs:178:21
|
--> $DIR/cast.rs:179:21
|
||||||
|
|
|
|
||||||
LL | let _ = self as i8;
|
LL | let _ = self as i8;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | let _ = i8::try_from(self);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `main::E5::A` to `i8` will truncate the value
|
error: casting `main::E5::A` to `i8` will truncate the value
|
||||||
--> $DIR/cast.rs:179:21
|
--> $DIR/cast.rs:180:21
|
||||||
|
|
|
|
||||||
LL | let _ = Self::A as i8;
|
LL | let _ = Self::A as i8;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: casting `main::E6` to `i16` may truncate the value
|
error: casting `main::E6` to `i16` may truncate the value
|
||||||
--> $DIR/cast.rs:193:21
|
--> $DIR/cast.rs:194:21
|
||||||
|
|
|
|
||||||
LL | let _ = self as i16;
|
LL | let _ = self as i16;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | let _ = i16::try_from(self);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `main::E7` to `usize` may truncate the value on targets with 32-bit wide pointers
|
error: casting `main::E7` to `usize` may truncate the value on targets with 32-bit wide pointers
|
||||||
--> $DIR/cast.rs:208:21
|
--> $DIR/cast.rs:209:21
|
||||||
|
|
|
|
||||||
LL | let _ = self as usize;
|
LL | let _ = self as usize;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | let _ = usize::try_from(self);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `main::E10` to `u16` may truncate the value
|
error: casting `main::E10` to `u16` may truncate the value
|
||||||
--> $DIR/cast.rs:249:21
|
--> $DIR/cast.rs:250:21
|
||||||
|
|
|
|
||||||
LL | let _ = self as u16;
|
LL | let _ = self as u16;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | let _ = u16::try_from(self);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `u32` to `u8` may truncate the value
|
error: casting `u32` to `u8` may truncate the value
|
||||||
--> $DIR/cast.rs:257:13
|
--> $DIR/cast.rs:258:13
|
||||||
|
|
|
|
||||||
LL | let c = (q >> 16) as u8;
|
LL | let c = (q >> 16) as u8;
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | let c = u8::try_from((q >> 16));
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `u32` to `u8` may truncate the value
|
error: casting `u32` to `u8` may truncate the value
|
||||||
--> $DIR/cast.rs:260:13
|
--> $DIR/cast.rs:261:13
|
||||||
|
|
|
|
||||||
LL | let c = (q / 1000) as u8;
|
LL | let c = (q / 1000) as u8;
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | let c = u8::try_from((q / 1000));
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: aborting due to 33 previous errors
|
error: aborting due to 36 previous errors
|
||||||
|
|
||||||
|
@ -4,7 +4,12 @@ error: casting `isize` to `i8` may truncate the value
|
|||||||
LL | 1isize as i8;
|
LL | 1isize as i8;
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
= note: `-D clippy::cast-possible-truncation` implied by `-D warnings`
|
= note: `-D clippy::cast-possible-truncation` implied by `-D warnings`
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | i8::try_from(1isize);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `isize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`isize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)
|
error: casting `isize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`isize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)
|
||||||
--> $DIR/cast_size.rs:15:5
|
--> $DIR/cast_size.rs:15:5
|
||||||
@ -37,24 +42,48 @@ error: casting `isize` to `i32` may truncate the value on targets with 64-bit wi
|
|||||||
|
|
|
|
||||||
LL | 1isize as i32;
|
LL | 1isize as i32;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | i32::try_from(1isize);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `isize` to `u32` may truncate the value on targets with 64-bit wide pointers
|
error: casting `isize` to `u32` may truncate the value on targets with 64-bit wide pointers
|
||||||
--> $DIR/cast_size.rs:20:5
|
--> $DIR/cast_size.rs:20:5
|
||||||
|
|
|
|
||||||
LL | 1isize as u32;
|
LL | 1isize as u32;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | u32::try_from(1isize);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers
|
error: casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers
|
||||||
--> $DIR/cast_size.rs:21:5
|
--> $DIR/cast_size.rs:21:5
|
||||||
|
|
|
|
||||||
LL | 1usize as u32;
|
LL | 1usize as u32;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | u32::try_from(1usize);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers
|
error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers
|
||||||
--> $DIR/cast_size.rs:22:5
|
--> $DIR/cast_size.rs:22:5
|
||||||
|
|
|
|
||||||
LL | 1usize as i32;
|
LL | 1usize as i32;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | i32::try_from(1usize);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers
|
error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers
|
||||||
--> $DIR/cast_size.rs:22:5
|
--> $DIR/cast_size.rs:22:5
|
||||||
@ -69,18 +98,36 @@ error: casting `i64` to `isize` may truncate the value on targets with 32-bit wi
|
|||||||
|
|
|
|
||||||
LL | 1i64 as isize;
|
LL | 1i64 as isize;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | isize::try_from(1i64);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers
|
error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers
|
||||||
--> $DIR/cast_size.rs:25:5
|
--> $DIR/cast_size.rs:25:5
|
||||||
|
|
|
|
||||||
LL | 1i64 as usize;
|
LL | 1i64 as usize;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | usize::try_from(1i64);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers
|
error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers
|
||||||
--> $DIR/cast_size.rs:26:5
|
--> $DIR/cast_size.rs:26:5
|
||||||
|
|
|
|
||||||
LL | 1u64 as isize;
|
LL | 1u64 as isize;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | isize::try_from(1u64);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers
|
error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers
|
||||||
--> $DIR/cast_size.rs:26:5
|
--> $DIR/cast_size.rs:26:5
|
||||||
@ -93,6 +140,12 @@ error: casting `u64` to `usize` may truncate the value on targets with 32-bit wi
|
|||||||
|
|
|
|
||||||
LL | 1u64 as usize;
|
LL | 1u64 as usize;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_precision_loss)]` ...
|
||||||
|
help: ... or use `try_from` and handle the error accordingly
|
||||||
|
|
|
||||||
|
LL | usize::try_from(1u64);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers
|
error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers
|
||||||
--> $DIR/cast_size.rs:28:5
|
--> $DIR/cast_size.rs:28:5
|
||||||
|
@ -1,34 +1,34 @@
|
|||||||
error: item name starts with its containing module's name
|
error: item name starts with its containing module's name
|
||||||
--> $DIR/module_name_repetitions.rs:8:5
|
--> $DIR/module_name_repetitions.rs:8:12
|
||||||
|
|
|
|
||||||
LL | pub fn foo_bar() {}
|
LL | pub fn foo_bar() {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
|
|
||||||
= note: `-D clippy::module-name-repetitions` implied by `-D warnings`
|
= note: `-D clippy::module-name-repetitions` implied by `-D warnings`
|
||||||
|
|
||||||
error: item name ends with its containing module's name
|
error: item name ends with its containing module's name
|
||||||
--> $DIR/module_name_repetitions.rs:9:5
|
--> $DIR/module_name_repetitions.rs:9:12
|
||||||
|
|
|
|
||||||
LL | pub fn bar_foo() {}
|
LL | pub fn bar_foo() {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: item name starts with its containing module's name
|
error: item name starts with its containing module's name
|
||||||
--> $DIR/module_name_repetitions.rs:10:5
|
--> $DIR/module_name_repetitions.rs:10:16
|
||||||
|
|
|
|
||||||
LL | pub struct FooCake;
|
LL | pub struct FooCake;
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: item name ends with its containing module's name
|
error: item name ends with its containing module's name
|
||||||
--> $DIR/module_name_repetitions.rs:11:5
|
--> $DIR/module_name_repetitions.rs:11:14
|
||||||
|
|
|
|
||||||
LL | pub enum CakeFoo {}
|
LL | pub enum CakeFoo {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: item name starts with its containing module's name
|
error: item name starts with its containing module's name
|
||||||
--> $DIR/module_name_repetitions.rs:12:5
|
--> $DIR/module_name_repetitions.rs:12:16
|
||||||
|
|
|
|
||||||
LL | pub struct Foo7Bar;
|
LL | pub struct Foo7Bar;
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
110
src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs
Normal file
110
src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
#![allow(unused)]
|
||||||
|
#![allow(deref_nullptr)]
|
||||||
|
#![allow(clippy::unnecessary_operation)]
|
||||||
|
#![allow(clippy::drop_copy)]
|
||||||
|
#![warn(clippy::multiple_unsafe_ops_per_block)]
|
||||||
|
|
||||||
|
use core::arch::asm;
|
||||||
|
|
||||||
|
fn raw_ptr() -> *const () {
|
||||||
|
core::ptr::null()
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn not_very_safe() {}
|
||||||
|
|
||||||
|
struct Sample;
|
||||||
|
|
||||||
|
impl Sample {
|
||||||
|
unsafe fn not_very_safe(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
const sample: Sample = Sample;
|
||||||
|
|
||||||
|
union U {
|
||||||
|
i: i32,
|
||||||
|
u: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
static mut STATIC: i32 = 0;
|
||||||
|
|
||||||
|
fn test1() {
|
||||||
|
unsafe {
|
||||||
|
STATIC += 1;
|
||||||
|
not_very_safe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test2() {
|
||||||
|
let u = U { i: 0 };
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
drop(u.u);
|
||||||
|
*raw_ptr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test3() {
|
||||||
|
unsafe {
|
||||||
|
asm!("nop");
|
||||||
|
sample.not_very_safe();
|
||||||
|
STATIC = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_all() {
|
||||||
|
let u = U { i: 0 };
|
||||||
|
unsafe {
|
||||||
|
drop(u.u);
|
||||||
|
drop(STATIC);
|
||||||
|
sample.not_very_safe();
|
||||||
|
not_very_safe();
|
||||||
|
*raw_ptr();
|
||||||
|
asm!("nop");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no lint
|
||||||
|
fn correct1() {
|
||||||
|
unsafe {
|
||||||
|
STATIC += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no lint
|
||||||
|
fn correct2() {
|
||||||
|
unsafe {
|
||||||
|
STATIC += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
*raw_ptr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no lint
|
||||||
|
fn correct3() {
|
||||||
|
let u = U { u: 0 };
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
not_very_safe();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
drop(u.i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// tests from the issue (https://github.com/rust-lang/rust-clippy/issues/10064)
|
||||||
|
|
||||||
|
unsafe fn read_char_bad(ptr: *const u8) -> char {
|
||||||
|
unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// no lint
|
||||||
|
unsafe fn read_char_good(ptr: *const u8) -> char {
|
||||||
|
let int_value = unsafe { *ptr.cast::<u32>() };
|
||||||
|
unsafe { core::char::from_u32_unchecked(int_value) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
129
src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.stderr
Normal file
129
src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.stderr
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
error: this `unsafe` block contains 2 unsafe operations, expected only one
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:32:5
|
||||||
|
|
|
||||||
|
LL | / unsafe {
|
||||||
|
LL | | STATIC += 1;
|
||||||
|
LL | | not_very_safe();
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
|
|
||||||
|
note: modification of a mutable static occurs here
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:33:9
|
||||||
|
|
|
||||||
|
LL | STATIC += 1;
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
note: unsafe function call occurs here
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:34:9
|
||||||
|
|
|
||||||
|
LL | not_very_safe();
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
= note: `-D clippy::multiple-unsafe-ops-per-block` implied by `-D warnings`
|
||||||
|
|
||||||
|
error: this `unsafe` block contains 2 unsafe operations, expected only one
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:41:5
|
||||||
|
|
|
||||||
|
LL | / unsafe {
|
||||||
|
LL | | drop(u.u);
|
||||||
|
LL | | *raw_ptr();
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
|
|
||||||
|
note: union field access occurs here
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:42:14
|
||||||
|
|
|
||||||
|
LL | drop(u.u);
|
||||||
|
| ^^^
|
||||||
|
note: raw pointer dereference occurs here
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:43:9
|
||||||
|
|
|
||||||
|
LL | *raw_ptr();
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: this `unsafe` block contains 3 unsafe operations, expected only one
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:48:5
|
||||||
|
|
|
||||||
|
LL | / unsafe {
|
||||||
|
LL | | asm!("nop");
|
||||||
|
LL | | sample.not_very_safe();
|
||||||
|
LL | | STATIC = 0;
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
|
|
||||||
|
note: inline assembly used here
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:49:9
|
||||||
|
|
|
||||||
|
LL | asm!("nop");
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
note: unsafe method call occurs here
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:50:9
|
||||||
|
|
|
||||||
|
LL | sample.not_very_safe();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: modification of a mutable static occurs here
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:51:9
|
||||||
|
|
|
||||||
|
LL | STATIC = 0;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: this `unsafe` block contains 6 unsafe operations, expected only one
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:57:5
|
||||||
|
|
|
||||||
|
LL | / unsafe {
|
||||||
|
LL | | drop(u.u);
|
||||||
|
LL | | drop(STATIC);
|
||||||
|
LL | | sample.not_very_safe();
|
||||||
|
... |
|
||||||
|
LL | | asm!("nop");
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
|
|
||||||
|
note: union field access occurs here
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:58:14
|
||||||
|
|
|
||||||
|
LL | drop(u.u);
|
||||||
|
| ^^^
|
||||||
|
note: access of a mutable static occurs here
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:59:14
|
||||||
|
|
|
||||||
|
LL | drop(STATIC);
|
||||||
|
| ^^^^^^
|
||||||
|
note: unsafe method call occurs here
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:60:9
|
||||||
|
|
|
||||||
|
LL | sample.not_very_safe();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: unsafe function call occurs here
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:61:9
|
||||||
|
|
|
||||||
|
LL | not_very_safe();
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
note: raw pointer dereference occurs here
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:62:9
|
||||||
|
|
|
||||||
|
LL | *raw_ptr();
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
note: inline assembly used here
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:63:9
|
||||||
|
|
|
||||||
|
LL | asm!("nop");
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: this `unsafe` block contains 2 unsafe operations, expected only one
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:101:5
|
||||||
|
|
|
||||||
|
LL | unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: unsafe function call occurs here
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:101:14
|
||||||
|
|
|
||||||
|
LL | unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: raw pointer dereference occurs here
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:101:39
|
||||||
|
|
|
||||||
|
LL | unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
@ -31,6 +31,16 @@ fn test_no_semicolon() -> bool {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
fn test_multiple_semicolon() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
fn test_multiple_semicolon_with_spaces() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fn test_if_block() -> bool {
|
fn test_if_block() -> bool {
|
||||||
if true {
|
if true {
|
||||||
true
|
true
|
||||||
|
@ -31,6 +31,16 @@ fn test_no_semicolon() -> bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
fn test_multiple_semicolon() -> bool {
|
||||||
|
return true;;;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
fn test_multiple_semicolon_with_spaces() -> bool {
|
||||||
|
return true;; ; ;
|
||||||
|
}
|
||||||
|
|
||||||
fn test_if_block() -> bool {
|
fn test_if_block() -> bool {
|
||||||
if true {
|
if true {
|
||||||
return true;
|
return true;
|
||||||
|
@ -16,7 +16,23 @@ LL | return true;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:36:9
|
--> $DIR/needless_return.rs:36:5
|
||||||
|
|
|
||||||
|
LL | return true;;;
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: remove `return`
|
||||||
|
|
||||||
|
error: unneeded `return` statement
|
||||||
|
--> $DIR/needless_return.rs:41:5
|
||||||
|
|
|
||||||
|
LL | return true;; ; ;
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: remove `return`
|
||||||
|
|
||||||
|
error: unneeded `return` statement
|
||||||
|
--> $DIR/needless_return.rs:46:9
|
||||||
|
|
|
|
||||||
LL | return true;
|
LL | return true;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
@ -24,7 +40,7 @@ LL | return true;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:38:9
|
--> $DIR/needless_return.rs:48:9
|
||||||
|
|
|
|
||||||
LL | return false;
|
LL | return false;
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
@ -32,7 +48,7 @@ LL | return false;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:44:17
|
--> $DIR/needless_return.rs:54:17
|
||||||
|
|
|
|
||||||
LL | true => return false,
|
LL | true => return false,
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
@ -40,7 +56,7 @@ LL | true => return false,
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:46:13
|
--> $DIR/needless_return.rs:56:13
|
||||||
|
|
|
|
||||||
LL | return true;
|
LL | return true;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
@ -48,7 +64,7 @@ LL | return true;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:53:9
|
--> $DIR/needless_return.rs:63:9
|
||||||
|
|
|
|
||||||
LL | return true;
|
LL | return true;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
@ -56,7 +72,7 @@ LL | return true;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:55:16
|
--> $DIR/needless_return.rs:65:16
|
||||||
|
|
|
|
||||||
LL | let _ = || return true;
|
LL | let _ = || return true;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
@ -64,7 +80,7 @@ LL | let _ = || return true;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:59:5
|
--> $DIR/needless_return.rs:69:5
|
||||||
|
|
|
|
||||||
LL | return the_answer!();
|
LL | return the_answer!();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -72,7 +88,7 @@ LL | return the_answer!();
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:62:21
|
--> $DIR/needless_return.rs:72:21
|
||||||
|
|
|
|
||||||
LL | fn test_void_fun() {
|
LL | fn test_void_fun() {
|
||||||
| _____________________^
|
| _____________________^
|
||||||
@ -82,7 +98,7 @@ LL | | return;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:67:11
|
--> $DIR/needless_return.rs:77:11
|
||||||
|
|
|
|
||||||
LL | if b {
|
LL | if b {
|
||||||
| ___________^
|
| ___________^
|
||||||
@ -92,7 +108,7 @@ LL | | return;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:69:13
|
--> $DIR/needless_return.rs:79:13
|
||||||
|
|
|
|
||||||
LL | } else {
|
LL | } else {
|
||||||
| _____________^
|
| _____________^
|
||||||
@ -102,7 +118,7 @@ LL | | return;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:77:14
|
--> $DIR/needless_return.rs:87:14
|
||||||
|
|
|
|
||||||
LL | _ => return,
|
LL | _ => return,
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
@ -110,7 +126,7 @@ LL | _ => return,
|
|||||||
= help: replace `return` with a unit value
|
= help: replace `return` with a unit value
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:85:24
|
--> $DIR/needless_return.rs:95:24
|
||||||
|
|
|
|
||||||
LL | let _ = 42;
|
LL | let _ = 42;
|
||||||
| ________________________^
|
| ________________________^
|
||||||
@ -120,7 +136,7 @@ LL | | return;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:88:14
|
--> $DIR/needless_return.rs:98:14
|
||||||
|
|
|
|
||||||
LL | _ => return,
|
LL | _ => return,
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
@ -128,7 +144,7 @@ LL | _ => return,
|
|||||||
= help: replace `return` with a unit value
|
= help: replace `return` with a unit value
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:101:9
|
--> $DIR/needless_return.rs:111:9
|
||||||
|
|
|
|
||||||
LL | return String::from("test");
|
LL | return String::from("test");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -136,7 +152,7 @@ LL | return String::from("test");
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:103:9
|
--> $DIR/needless_return.rs:113:9
|
||||||
|
|
|
|
||||||
LL | return String::new();
|
LL | return String::new();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -144,7 +160,7 @@ LL | return String::new();
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:125:32
|
--> $DIR/needless_return.rs:135:32
|
||||||
|
|
|
|
||||||
LL | bar.unwrap_or_else(|_| return)
|
LL | bar.unwrap_or_else(|_| return)
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
@ -152,7 +168,7 @@ LL | bar.unwrap_or_else(|_| return)
|
|||||||
= help: replace `return` with an empty block
|
= help: replace `return` with an empty block
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:129:21
|
--> $DIR/needless_return.rs:139:21
|
||||||
|
|
|
|
||||||
LL | let _ = || {
|
LL | let _ = || {
|
||||||
| _____________________^
|
| _____________________^
|
||||||
@ -162,7 +178,7 @@ LL | | return;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:132:20
|
--> $DIR/needless_return.rs:142:20
|
||||||
|
|
|
|
||||||
LL | let _ = || return;
|
LL | let _ = || return;
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
@ -170,7 +186,7 @@ LL | let _ = || return;
|
|||||||
= help: replace `return` with an empty block
|
= help: replace `return` with an empty block
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:138:32
|
--> $DIR/needless_return.rs:148:32
|
||||||
|
|
|
|
||||||
LL | res.unwrap_or_else(|_| return Foo)
|
LL | res.unwrap_or_else(|_| return Foo)
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
@ -178,7 +194,7 @@ LL | res.unwrap_or_else(|_| return Foo)
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:147:5
|
--> $DIR/needless_return.rs:157:5
|
||||||
|
|
|
|
||||||
LL | return true;
|
LL | return true;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
@ -186,7 +202,7 @@ LL | return true;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:151:5
|
--> $DIR/needless_return.rs:161:5
|
||||||
|
|
|
|
||||||
LL | return true;
|
LL | return true;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
@ -194,7 +210,7 @@ LL | return true;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:156:9
|
--> $DIR/needless_return.rs:166:9
|
||||||
|
|
|
|
||||||
LL | return true;
|
LL | return true;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
@ -202,7 +218,7 @@ LL | return true;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:158:9
|
--> $DIR/needless_return.rs:168:9
|
||||||
|
|
|
|
||||||
LL | return false;
|
LL | return false;
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
@ -210,7 +226,7 @@ LL | return false;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:164:17
|
--> $DIR/needless_return.rs:174:17
|
||||||
|
|
|
|
||||||
LL | true => return false,
|
LL | true => return false,
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
@ -218,7 +234,7 @@ LL | true => return false,
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:166:13
|
--> $DIR/needless_return.rs:176:13
|
||||||
|
|
|
|
||||||
LL | return true;
|
LL | return true;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
@ -226,7 +242,7 @@ LL | return true;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:173:9
|
--> $DIR/needless_return.rs:183:9
|
||||||
|
|
|
|
||||||
LL | return true;
|
LL | return true;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
@ -234,7 +250,7 @@ LL | return true;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:175:16
|
--> $DIR/needless_return.rs:185:16
|
||||||
|
|
|
|
||||||
LL | let _ = || return true;
|
LL | let _ = || return true;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
@ -242,7 +258,7 @@ LL | let _ = || return true;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:179:5
|
--> $DIR/needless_return.rs:189:5
|
||||||
|
|
|
|
||||||
LL | return the_answer!();
|
LL | return the_answer!();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -250,7 +266,7 @@ LL | return the_answer!();
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:182:33
|
--> $DIR/needless_return.rs:192:33
|
||||||
|
|
|
|
||||||
LL | async fn async_test_void_fun() {
|
LL | async fn async_test_void_fun() {
|
||||||
| _________________________________^
|
| _________________________________^
|
||||||
@ -260,7 +276,7 @@ LL | | return;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:187:11
|
--> $DIR/needless_return.rs:197:11
|
||||||
|
|
|
|
||||||
LL | if b {
|
LL | if b {
|
||||||
| ___________^
|
| ___________^
|
||||||
@ -270,7 +286,7 @@ LL | | return;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:189:13
|
--> $DIR/needless_return.rs:199:13
|
||||||
|
|
|
|
||||||
LL | } else {
|
LL | } else {
|
||||||
| _____________^
|
| _____________^
|
||||||
@ -280,7 +296,7 @@ LL | | return;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:197:14
|
--> $DIR/needless_return.rs:207:14
|
||||||
|
|
|
|
||||||
LL | _ => return,
|
LL | _ => return,
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
@ -288,7 +304,7 @@ LL | _ => return,
|
|||||||
= help: replace `return` with a unit value
|
= help: replace `return` with a unit value
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:210:9
|
--> $DIR/needless_return.rs:220:9
|
||||||
|
|
|
|
||||||
LL | return String::from("test");
|
LL | return String::from("test");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -296,7 +312,7 @@ LL | return String::from("test");
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:212:9
|
--> $DIR/needless_return.rs:222:9
|
||||||
|
|
|
|
||||||
LL | return String::new();
|
LL | return String::new();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -304,7 +320,7 @@ LL | return String::new();
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:228:5
|
--> $DIR/needless_return.rs:238:5
|
||||||
|
|
|
|
||||||
LL | return format!("Hello {}", "world!");
|
LL | return format!("Hello {}", "world!");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -312,7 +328,7 @@ LL | return format!("Hello {}", "world!");
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:239:9
|
--> $DIR/needless_return.rs:249:9
|
||||||
|
|
|
|
||||||
LL | return true;
|
LL | return true;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
@ -320,7 +336,7 @@ LL | return true;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:241:9
|
--> $DIR/needless_return.rs:251:9
|
||||||
|
|
|
|
||||||
LL | return false;
|
LL | return false;
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
@ -328,7 +344,7 @@ LL | return false;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:248:13
|
--> $DIR/needless_return.rs:258:13
|
||||||
|
|
|
|
||||||
LL | return 10;
|
LL | return 10;
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
@ -336,7 +352,7 @@ LL | return 10;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:251:13
|
--> $DIR/needless_return.rs:261:13
|
||||||
|
|
|
|
||||||
LL | return 100;
|
LL | return 100;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
@ -344,7 +360,7 @@ LL | return 100;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:259:9
|
--> $DIR/needless_return.rs:269:9
|
||||||
|
|
|
|
||||||
LL | return 0;
|
LL | return 0;
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
@ -352,7 +368,7 @@ LL | return 0;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:266:13
|
--> $DIR/needless_return.rs:276:13
|
||||||
|
|
|
|
||||||
LL | return *(x as *const isize);
|
LL | return *(x as *const isize);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -360,7 +376,7 @@ LL | return *(x as *const isize);
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:268:13
|
--> $DIR/needless_return.rs:278:13
|
||||||
|
|
|
|
||||||
LL | return !*(x as *const isize);
|
LL | return !*(x as *const isize);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -368,7 +384,7 @@ LL | return !*(x as *const isize);
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:275:20
|
--> $DIR/needless_return.rs:285:20
|
||||||
|
|
|
|
||||||
LL | let _ = 42;
|
LL | let _ = 42;
|
||||||
| ____________________^
|
| ____________________^
|
||||||
@ -379,7 +395,7 @@ LL | | return;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:282:20
|
--> $DIR/needless_return.rs:292:20
|
||||||
|
|
|
|
||||||
LL | let _ = 42; return;
|
LL | let _ = 42; return;
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
@ -387,7 +403,7 @@ LL | let _ = 42; return;
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:294:9
|
--> $DIR/needless_return.rs:304:9
|
||||||
|
|
|
|
||||||
LL | return Ok(format!("ok!"));
|
LL | return Ok(format!("ok!"));
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -395,12 +411,12 @@ LL | return Ok(format!("ok!"));
|
|||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: unneeded `return` statement
|
error: unneeded `return` statement
|
||||||
--> $DIR/needless_return.rs:296:9
|
--> $DIR/needless_return.rs:306:9
|
||||||
|
|
|
|
||||||
LL | return Err(format!("err!"));
|
LL | return Err(format!("err!"));
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: remove `return`
|
= help: remove `return`
|
||||||
|
|
||||||
error: aborting due to 48 previous errors
|
error: aborting due to 50 previous errors
|
||||||
|
|
||||||
|
@ -51,6 +51,8 @@ fn main() {
|
|||||||
// e is a function pointer type and U is an integer; fptr-addr-cast
|
// e is a function pointer type and U is an integer; fptr-addr-cast
|
||||||
let _usize_from_fn_ptr_transmute = unsafe { foo as usize };
|
let _usize_from_fn_ptr_transmute = unsafe { foo as usize };
|
||||||
let _usize_from_fn_ptr = foo as *const usize;
|
let _usize_from_fn_ptr = foo as *const usize;
|
||||||
|
|
||||||
|
let _usize_from_ref = unsafe { &1u32 as *const u32 as usize };
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a ref-to-ptr cast of this form where the pointer type points to a type other
|
// If a ref-to-ptr cast of this form where the pointer type points to a type other
|
||||||
|
@ -51,6 +51,8 @@ fn main() {
|
|||||||
// e is a function pointer type and U is an integer; fptr-addr-cast
|
// e is a function pointer type and U is an integer; fptr-addr-cast
|
||||||
let _usize_from_fn_ptr_transmute = unsafe { transmute::<fn(usize) -> u8, usize>(foo) };
|
let _usize_from_fn_ptr_transmute = unsafe { transmute::<fn(usize) -> u8, usize>(foo) };
|
||||||
let _usize_from_fn_ptr = foo as *const usize;
|
let _usize_from_fn_ptr = foo as *const usize;
|
||||||
|
|
||||||
|
let _usize_from_ref = unsafe { transmute::<*const u32, usize>(&1u32) };
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a ref-to-ptr cast of this form where the pointer type points to a type other
|
// If a ref-to-ptr cast of this form where the pointer type points to a type other
|
||||||
|
@ -46,11 +46,17 @@ error: transmute from `fn(usize) -> u8` to `usize` which could be expressed as a
|
|||||||
LL | let _usize_from_fn_ptr_transmute = unsafe { transmute::<fn(usize) -> u8, usize>(foo) };
|
LL | let _usize_from_fn_ptr_transmute = unsafe { transmute::<fn(usize) -> u8, usize>(foo) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `foo as usize`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `foo as usize`
|
||||||
|
|
||||||
|
error: transmute from `*const u32` to `usize` which could be expressed as a pointer cast instead
|
||||||
|
--> $DIR/transmutes_expressible_as_ptr_casts.rs:55:36
|
||||||
|
|
|
||||||
|
LL | let _usize_from_ref = unsafe { transmute::<*const u32, usize>(&1u32) };
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&1u32 as *const u32 as usize`
|
||||||
|
|
||||||
error: transmute from a reference to a pointer
|
error: transmute from a reference to a pointer
|
||||||
--> $DIR/transmutes_expressible_as_ptr_casts.rs:64:14
|
--> $DIR/transmutes_expressible_as_ptr_casts.rs:66:14
|
||||||
|
|
|
|
||||||
LL | unsafe { transmute::<&[i32; 1], *const u8>(in_param) }
|
LL | unsafe { transmute::<&[i32; 1], *const u8>(in_param) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `in_param as *const [i32; 1] as *const u8`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `in_param as *const [i32; 1] as *const u8`
|
||||||
|
|
||||||
error: aborting due to 8 previous errors
|
error: aborting due to 9 previous errors
|
||||||
|
|
||||||
|
@ -48,4 +48,21 @@ fn unnecessary_on_stmt_and_expr() -> u32 {
|
|||||||
24
|
24
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod issue_10084 {
|
||||||
|
unsafe fn bar() -> i32 {
|
||||||
|
42
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! foo {
|
||||||
|
() => {
|
||||||
|
// SAFETY: This is necessary
|
||||||
|
unsafe { bar() }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
foo!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
Loading…
Reference in New Issue
Block a user