mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 16:54:01 +00:00
Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup
This commit is contained in:
parent
f30fc0a5e2
commit
a1b75c5108
120
CHANGELOG.md
120
CHANGELOG.md
@ -6,11 +6,126 @@ document.
|
||||
|
||||
## Unreleased / Beta / In Rust Nightly
|
||||
|
||||
[7f27e2e7...master](https://github.com/rust-lang/rust-clippy/compare/7f27e2e7...master)
|
||||
[149392b0...master](https://github.com/rust-lang/rust-clippy/compare/149392b0...master)
|
||||
|
||||
## Rust 1.69
|
||||
|
||||
Current stable, released 2023-04-20
|
||||
|
||||
[7f27e2e7...149392b0](https://github.com/rust-lang/rust-clippy/compare/7f27e2e7...149392b0)
|
||||
|
||||
### New Lints
|
||||
|
||||
* [`no_mangle_with_rust_abi`]
|
||||
[#10369](https://github.com/rust-lang/rust-clippy/pull/10369)
|
||||
* [`significant_drop_tightening`]
|
||||
[#10163](https://github.com/rust-lang/rust-clippy/pull/10163)
|
||||
* [`suspicious_command_arg_space`]
|
||||
[#10317](https://github.com/rust-lang/rust-clippy/pull/10317)
|
||||
* [`let_underscore_untyped`]
|
||||
[#10356](https://github.com/rust-lang/rust-clippy/pull/10356)
|
||||
* [`question_mark_used`]
|
||||
[#10342](https://github.com/rust-lang/rust-clippy/pull/10342)
|
||||
* [`extra_unused_type_parameters`]
|
||||
[#10028](https://github.com/rust-lang/rust-clippy/pull/10028)
|
||||
* [`impl_trait_in_params`]
|
||||
[10197](https://github.com/rust-lang/rust-clippy/pull/10197)
|
||||
* [`transmute_int_to_non_zero`]
|
||||
[#10360](https://github.com/rust-lang/rust-clippy/pull/10360)
|
||||
* [`multiple_unsafe_ops_per_block`]
|
||||
[#10206](https://github.com/rust-lang/rust-clippy/pull/10206)
|
||||
|
||||
### Moves and Deprecations
|
||||
|
||||
* Moved [`uninlined_format_args`] to `pedantic` (Now allow-by-default)
|
||||
[#10265](https://github.com/rust-lang/rust-clippy/pull/10265)
|
||||
* Moved [`unchecked_duration_subtraction`] to `pedantic` (Now allow-by-default)
|
||||
[#10194](https://github.com/rust-lang/rust-clippy/pull/10194)
|
||||
|
||||
### Enhancements
|
||||
|
||||
* [`arithmetic_side_effects`]: No longer lints, if safe constant values are used.
|
||||
[#10310](https://github.com/rust-lang/rust-clippy/pull/10310)
|
||||
* [`needless_lifetimes`]: Now works in local macros
|
||||
[#10257](https://github.com/rust-lang/rust-clippy/pull/10257)
|
||||
* [`unused_io_amount`]: Now detects usages of `is_ok` and `is_err`
|
||||
[#10225](https://github.com/rust-lang/rust-clippy/pull/10225)
|
||||
* [`missing_docs_in_private_items`]: Added new configuration `missing-docs-in-crate-items` to lint
|
||||
on items visible within the current crate. For example, `pub(crate)` items.
|
||||
[#10303](https://github.com/rust-lang/rust-clippy/pull/10303)
|
||||
* [`almost_swapped`]: Now detects almost swaps using `let` statements
|
||||
[#10177](https://github.com/rust-lang/rust-clippy/pull/10177)
|
||||
* [`wildcard_enum_match_arm`]: Now lints missing private variants, for local enums
|
||||
[#10250](https://github.com/rust-lang/rust-clippy/pull/10250)
|
||||
|
||||
### False Positive Fixes
|
||||
|
||||
* [`explicit_auto_deref`]: Now considers projections, when determining if auto deref is applicable
|
||||
[#10386](https://github.com/rust-lang/rust-clippy/pull/10386)
|
||||
* [`manual_let_else`]: Now considers side effects of branches, before linting
|
||||
[#10336](https://github.com/rust-lang/rust-clippy/pull/10336)
|
||||
* [`uninlined_format_args`]: No longer lints for arguments with generic parameters
|
||||
[#10343](https://github.com/rust-lang/rust-clippy/pull/10343)
|
||||
* [`needless_lifetimes`]: No longer lints signatures in macros, if the lifetime is a metavariable
|
||||
[#10380](https://github.com/rust-lang/rust-clippy/pull/10380)
|
||||
* [`len_without_is_empty`]: No longer lints, if `len` as a non-default signature
|
||||
[#10255](https://github.com/rust-lang/rust-clippy/pull/10255)
|
||||
* [`unusual_byte_groupings`]: Relaxed the required restrictions for specific sizes, to reduce false
|
||||
positives
|
||||
[#10353](https://github.com/rust-lang/rust-clippy/pull/10353)
|
||||
* [`manual_let_else`]: No longer lints `if-else` blocks if they can divergent
|
||||
[#10332](https://github.com/rust-lang/rust-clippy/pull/10332)
|
||||
* [`expect_used`], [`unwrap_used`], [`dbg_macro`], [`print_stdout`], [`print_stderr`]: No longer lint
|
||||
in test functions, if `allow-expect-in-tests` is set
|
||||
[#10391](https://github.com/rust-lang/rust-clippy/pull/10391)
|
||||
* [`unnecessary_safety_comment`]: No longer lints code inside macros
|
||||
[#10106](https://github.com/rust-lang/rust-clippy/pull/10106)
|
||||
* [`never_loop`]: No longer lints, for statements following break statements for outer blocks.
|
||||
[#10311](https://github.com/rust-lang/rust-clippy/pull/10311)
|
||||
|
||||
### Suggestion Fixes/Improvements
|
||||
|
||||
* [`box_default`]: The suggestion now includes the type for trait objects, when needed
|
||||
[#10382](https://github.com/rust-lang/rust-clippy/pull/10382)
|
||||
* [`cast_possible_truncation`]: Now suggests using `try_from` or allowing the lint
|
||||
[#10038](https://github.com/rust-lang/rust-clippy/pull/10038)
|
||||
* [`invalid_regex`]: Regex errors for non-literals or regular strings containing escape sequences will
|
||||
now show the complete error
|
||||
[#10231](https://github.com/rust-lang/rust-clippy/pull/10231)
|
||||
* [`transmutes_expressible_as_ptr_casts`]: The suggestion now works, if the base type is borrowed
|
||||
[#10193](https://github.com/rust-lang/rust-clippy/pull/10193)
|
||||
* [`needless_return`]: Now removes all semicolons on the same line
|
||||
[#10187](https://github.com/rust-lang/rust-clippy/pull/10187)
|
||||
* [`suspicious_to_owned`]: The suggestion now shows all options clearly
|
||||
[#10295](https://github.com/rust-lang/rust-clippy/pull/10295)
|
||||
* [`bytes_nth`]: Now suggests the correct replacement based on the context
|
||||
[#10361](https://github.com/rust-lang/rust-clippy/pull/10361)
|
||||
* [`bool_assert_comparison`]: The suggestion is now machine applicable
|
||||
[#10218](https://github.com/rust-lang/rust-clippy/pull/10218)
|
||||
* [`cast_possible_truncation`]: Corrected the lint name in the help message
|
||||
[#10330](https://github.com/rust-lang/rust-clippy/pull/10330)
|
||||
* [`needless_return`]: The suggestion now works on if sequences
|
||||
[#10345](https://github.com/rust-lang/rust-clippy/pull/10345)
|
||||
* [`needless_lifetimes`]: The suggestion is now machine applicable
|
||||
[#10222](https://github.com/rust-lang/rust-clippy/pull/10222)
|
||||
* [`map_entry`]: The suggestion no longer expands macros
|
||||
[#10346](https://github.com/rust-lang/rust-clippy/pull/10346)
|
||||
|
||||
### ICE Fixes
|
||||
|
||||
* [`needless_pass_by_value`]: Fixed an ICE, caused by how late bounds were handled
|
||||
[#10328](https://github.com/rust-lang/rust-clippy/pull/10328)
|
||||
* [`needless_borrow`]: No longer panics on ambiguous projections
|
||||
[#10403](https://github.com/rust-lang/rust-clippy/pull/10403)
|
||||
|
||||
### Documentation Improvements
|
||||
|
||||
* All configurations are now documented in the Clippy Book
|
||||
[#10199](https://github.com/rust-lang/rust-clippy/pull/10199)
|
||||
|
||||
## Rust 1.68
|
||||
|
||||
Current stable, released 2023-03-09
|
||||
Released 2023-03-09
|
||||
|
||||
[d822110d...7f27e2e7](https://github.com/rust-lang/rust-clippy/compare/d822110d...7f27e2e7)
|
||||
|
||||
@ -4615,6 +4730,7 @@ Released 2018-09-13
|
||||
[`invisible_characters`]: https://rust-lang.github.io/rust-clippy/master/index.html#invisible_characters
|
||||
[`is_digit_ascii_radix`]: https://rust-lang.github.io/rust-clippy/master/index.html#is_digit_ascii_radix
|
||||
[`items_after_statements`]: https://rust-lang.github.io/rust-clippy/master/index.html#items_after_statements
|
||||
[`items_after_test_module`]: https://rust-lang.github.io/rust-clippy/master/index.html#items_after_test_module
|
||||
[`iter_cloned_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_cloned_collect
|
||||
[`iter_count`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_count
|
||||
[`iter_kv_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_kv_map
|
||||
|
@ -22,13 +22,12 @@ path = "src/driver.rs"
|
||||
|
||||
[dependencies]
|
||||
clippy_lints = { path = "clippy_lints" }
|
||||
semver = "1.0"
|
||||
rustc_tools_util = "0.3.0"
|
||||
tempfile = { version = "3.2", optional = true }
|
||||
termize = "0.1"
|
||||
|
||||
[dev-dependencies]
|
||||
compiletest_rs = { version = "0.9", features = ["tmp"] }
|
||||
compiletest_rs = { version = "0.10", features = ["tmp"] }
|
||||
tester = "0.9"
|
||||
regex = "1.5"
|
||||
toml = "0.5"
|
||||
@ -49,7 +48,7 @@ if_chain = "1.0"
|
||||
itertools = "0.10.1"
|
||||
quote = "1.0"
|
||||
serde = { version = "1.0.125", features = ["derive"] }
|
||||
syn = { version = "1.0", features = ["full"] }
|
||||
syn = { version = "2.0", features = ["full"] }
|
||||
futures = "0.3"
|
||||
parking_lot = "0.12"
|
||||
tokio = { version = "1", features = ["io-util"] }
|
||||
|
@ -13,7 +13,9 @@
|
||||
- [Development](development/README.md)
|
||||
- [Basics](development/basics.md)
|
||||
- [Adding Lints](development/adding_lints.md)
|
||||
- [Lint Passes](development/lint_passes.md)
|
||||
- [Type Checking](development/type_checking.md)
|
||||
- [Macro Expansions](development/macro_expansions.md)
|
||||
- [Common Tools](development/common_tools_writing_lints.md)
|
||||
- [Infrastructure](development/infrastructure/README.md)
|
||||
- [Syncing changes between Clippy and rust-lang/rust](development/infrastructure/sync.md)
|
||||
|
@ -13,6 +13,24 @@ If this is your first time contributing to Clippy, you should first read the
|
||||
[Basics docs](basics.md). This will explain the basics on how to get the source
|
||||
code and how to compile and test the code.
|
||||
|
||||
## Additional Readings for Beginners
|
||||
|
||||
If a dear reader of this documentation has never taken a class on compilers
|
||||
and interpreters, it might be confusing as to why AST level deals with only
|
||||
the language's syntax. And some readers might not even understand what lexing,
|
||||
parsing, and AST mean.
|
||||
|
||||
This documentation serves by no means as a crash course on compilers or language design.
|
||||
And for details specifically related to Rust, the [Rustc Development Guide][rustc_dev_guide]
|
||||
is a far better choice to peruse.
|
||||
|
||||
The [Syntax and AST][ast] chapter and the [High-Level IR][hir] chapter are
|
||||
great introduction to the concepts mentioned in this chapter.
|
||||
|
||||
Some readers might also find the [introductory chapter][map_of_territory] of
|
||||
Robert Nystrom's _Crafting Interpreters_ a helpful overview of compiled and
|
||||
interpreted languages before jumping back to the Rustc guide.
|
||||
|
||||
## Writing code
|
||||
|
||||
If you have done the basic setup, it's time to start hacking.
|
||||
@ -37,6 +55,10 @@ book](../lints.md).
|
||||
> - Triage procedure
|
||||
> - Bors and Homu
|
||||
|
||||
[ast]: https://rustc-dev-guide.rust-lang.org/syntax-intro.html
|
||||
[hir]: https://rustc-dev-guide.rust-lang.org/hir.html
|
||||
[rustc_dev_guide]: https://rustc-dev-guide.rust-lang.org/
|
||||
[map_of_territory]: https://craftinginterpreters.com/a-map-of-the-territory.html
|
||||
[clippy_rfc]: https://github.com/rust-lang/rfcs/blob/master/text/2476-clippy-uno.md
|
||||
[rfc_stability]: https://github.com/rust-lang/rfcs/blob/master/text/2476-clippy-uno.md#stability-guarantees
|
||||
[rfc_lint_cats]: https://github.com/rust-lang/rfcs/blob/master/text/2476-clippy-uno.md#lint-audit-and-categories
|
||||
|
@ -164,7 +164,7 @@ The process of generating the `.stderr` file is the same, and prepending the
|
||||
## Rustfix tests
|
||||
|
||||
If the lint you are working on is making use of structured suggestions, the test
|
||||
file should include a `// run-rustfix` comment at the top. This will
|
||||
file should include a `//@run-rustfix` comment at the top. This will
|
||||
additionally run [rustfix] for that test. Rustfix will apply the suggestions
|
||||
from the lint to the code of the test file and compare that to the contents of a
|
||||
`.fixed` file.
|
||||
|
114
book/src/development/lint_passes.md
Normal file
114
book/src/development/lint_passes.md
Normal file
@ -0,0 +1,114 @@
|
||||
# Lint passes
|
||||
|
||||
Before working on the logic of a new lint, there is an important decision
|
||||
that every Clippy developer must make: to use
|
||||
[`EarlyLintPass`][early_lint_pass] or [`LateLintPass`][late_lint_pass].
|
||||
|
||||
In short, the `LateLintPass` has access to type and symbol information while the
|
||||
`EarlyLintPass` doesn't. If you don't need access to type information, use the
|
||||
`EarlyLintPass`.
|
||||
|
||||
Let us expand on these two traits more below.
|
||||
|
||||
## `EarlyLintPass`
|
||||
|
||||
If you examine the documentation on [`EarlyLintPass`][early_lint_pass] closely,
|
||||
you'll see that every method defined for this trait utilizes a
|
||||
[`EarlyContext`][early_context]. In `EarlyContext`'s documentation, it states:
|
||||
|
||||
> Context for lint checking of the AST, after expansion, before lowering to HIR.
|
||||
|
||||
Voilà. `EarlyLintPass` works only on the Abstract Syntax Tree (AST) level.
|
||||
And AST is generated during the [lexing and parsing][lexing_and_parsing] phase
|
||||
of code compilation. Therefore, it doesn't know what a symbol means or information about types, and it should
|
||||
be our trait choice for a new lint if the lint only deals with syntax-related issues.
|
||||
|
||||
While linting speed has not been a concern for Clippy,
|
||||
the `EarlyLintPass` is faster, and it should be your choice
|
||||
if you know for sure a lint does not need type information.
|
||||
|
||||
As a reminder, run the following command to generate boilerplate for lints
|
||||
that use `EarlyLintPass`:
|
||||
|
||||
```sh
|
||||
$ cargo dev new_lint --name=<your_new_lint> --pass=early --category=<your_category_choice>
|
||||
```
|
||||
|
||||
### Example for `EarlyLintPass`
|
||||
|
||||
Take a look at the following code:
|
||||
|
||||
```rust
|
||||
let x = OurUndefinedType;
|
||||
x.non_existing_method();
|
||||
```
|
||||
|
||||
From the AST perspective, both lines are "grammatically" correct.
|
||||
The assignment uses a `let` and ends with a semicolon. The invocation
|
||||
of a method looks fine, too. As programmers, we might raise a few
|
||||
questions already, but the parser is okay with it. This is what we
|
||||
mean when we say `EarlyLintPass` deals with only syntax on the AST level.
|
||||
|
||||
Alternatively, think of the `foo_functions` lint we mentioned in
|
||||
[define new lints](define_lints.md#name-the-lint) chapter.
|
||||
|
||||
We want the `foo_functions` lint to detect functions with `foo` as their name.
|
||||
Writing a lint that only checks for the name of a function means that we only
|
||||
work with the AST and don't have to access the type system at all (the type system is where
|
||||
`LateLintPass` comes into the picture).
|
||||
|
||||
## `LateLintPass`
|
||||
|
||||
In contrast to `EarlyLintPass`, `LateLintPass` contains type information.
|
||||
|
||||
If you examine the documentation on [`LateLintPass`][late_lint_pass] closely,
|
||||
you see that every method defined in this trait utilizes a
|
||||
[`LateContext`][late_context].
|
||||
|
||||
In `LateContext`'s documentation we will find methods that
|
||||
deal with type-checking, which do not exist in `EarlyContext`, such as:
|
||||
|
||||
- [`maybe_typeck_results`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/context/struct.LateContext.html#method.maybe_typeck_results)
|
||||
- [`typeck_results`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/context/struct.LateContext.html#method.typeck_results)
|
||||
|
||||
### Example for `LateLintPass`
|
||||
|
||||
Let us take a look with the following example:
|
||||
|
||||
```rust
|
||||
let x = OurUndefinedType;
|
||||
x.non_existing_method();
|
||||
```
|
||||
|
||||
These two lines of code are syntactically correct code from the perspective
|
||||
of the AST. We have an assignment and invoke a method on the variable that
|
||||
is of a type. Grammatically, everything is in order for the parser.
|
||||
|
||||
However, going down a level and looking at the type information,
|
||||
the compiler will notice that both `OurUndefinedType` and `non_existing_method()`
|
||||
**are undefined**.
|
||||
|
||||
As Clippy developers, to access such type information, we must implement
|
||||
`LateLintPass` on our lint.
|
||||
When you browse through Clippy's lints, you will notice that almost every lint
|
||||
is implemented in a `LateLintPass`, specifically because we often need to check
|
||||
not only for syntactic issues but also type information.
|
||||
|
||||
Another limitation of the `EarlyLintPass` is that the nodes are only identified
|
||||
by their position in the AST. This means that you can't just get an `id` and
|
||||
request a certain node. For most lints that is fine, but we have some lints
|
||||
that require the inspection of other nodes, which is easier at the HIR level.
|
||||
In these cases, `LateLintPass` is the better choice.
|
||||
|
||||
As a reminder, run the following command to generate boilerplate for lints
|
||||
that use `LateLintPass`:
|
||||
|
||||
```sh
|
||||
$ cargo dev new_lint --name=<your_new_lint> --pass=late --category=<your_category_choice>
|
||||
```
|
||||
|
||||
[early_context]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/context/struct.EarlyContext.html
|
||||
[early_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.EarlyLintPass.html
|
||||
[late_context]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/context/struct.LateContext.html
|
||||
[late_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html
|
||||
[lexing_and_parsing]: https://rustc-dev-guide.rust-lang.org/overview.html#lexing-and-parsing
|
158
book/src/development/macro_expansions.md
Normal file
158
book/src/development/macro_expansions.md
Normal file
@ -0,0 +1,158 @@
|
||||
# Dealing with macros and expansions
|
||||
|
||||
Sometimes we might encounter Rust macro expansions while working with Clippy.
|
||||
While macro expansions are not as dramatic and profound as the expansion
|
||||
of our universe, they can certainly bring chaos to the orderly world
|
||||
of code and logic.
|
||||
|
||||
The general rule of thumb is that we should ignore code with macro
|
||||
expansions when working with Clippy because the code can be dynamic
|
||||
in ways that are difficult or impossible for us to foresee.
|
||||
|
||||
## False Positives
|
||||
|
||||
What exactly do we mean by _dynamic in ways that are difficult to foresee_?
|
||||
|
||||
Macros are [expanded][expansion] in the `EarlyLintPass` level,
|
||||
so the Abstract Syntax Tree (AST) is generated in place of macros.
|
||||
This means the code which we work with in Clippy is already expanded.
|
||||
|
||||
If we wrote a new lint, there is a possibility that the lint is
|
||||
triggered in macro-generated code. Since this expanded macro code
|
||||
is not written by the macro's user but really by the macro's author,
|
||||
the user cannot and should not be responsible for fixing the issue
|
||||
that triggers the lint.
|
||||
|
||||
Besides, a [Span] in a macro can be changed by the macro author.
|
||||
Therefore, any lint check related to lines or columns should be
|
||||
avoided since they might be changed at any time and become unreliable
|
||||
or incorrect information.
|
||||
|
||||
Because of these unforeseeable or unstable behaviors, macro expansion
|
||||
should often not be regarded as a part of the stable API.
|
||||
This is also why most lints check if they are inside a macro or not
|
||||
before emitting suggestions to the end user to avoid false positives.
|
||||
|
||||
## How to Work with Macros
|
||||
|
||||
Several functions are available for working with macros.
|
||||
|
||||
### The `Span.from_expansion` method
|
||||
|
||||
We could utilize a `span`'s [`from_expansion`] method, which
|
||||
detects if the `span` is from a macro expansion / desugaring.
|
||||
This is a very common first step in a lint:
|
||||
|
||||
```rust
|
||||
if expr.span.from_expansion() {
|
||||
// We most likely want to ignore it.
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
### `Span.ctxt` method
|
||||
|
||||
The `span`'s context, given by the method [`ctxt`] and returning [SpanContext],
|
||||
represents if the span is from a macro expansion and, if it is, which
|
||||
macro call expanded this span.
|
||||
|
||||
Sometimes, it is useful to check if the context of two spans are equal.
|
||||
For instance, suppose we have the following line of code that would
|
||||
expand into `1 + 0`:
|
||||
|
||||
```rust
|
||||
// The following code expands to `1 + 0` for both `EarlyLintPass` and `LateLintPass`
|
||||
1 + mac!()
|
||||
```
|
||||
|
||||
Assuming that we'd collect the `1` expression as a variable `left` and the
|
||||
`0`/`mac!()` expression as a variable `right`, we can simply compare their
|
||||
contexts. If the context is different, then we most likely are dealing with a
|
||||
macro expansion and should just ignore it:
|
||||
|
||||
```rust
|
||||
if left.span.ctxt() != right.span.ctxt() {
|
||||
// The code author most likely cannot modify this expression
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
> **Note**: Code that is not from expansion is in the "root" context.
|
||||
> So any spans whose `from_expansion` returns `false` can be assumed
|
||||
> to have the same context. Because of this, using `span.from_expansion()`
|
||||
> is often sufficient.
|
||||
|
||||
Going a bit deeper, in a simple expression such as `a == b`,
|
||||
`a` and `b` have the same context.
|
||||
However, in a `macro_rules!` with `a == $b`, `$b` is expanded to
|
||||
an expression that contains a different context from `a`.
|
||||
|
||||
Take a look at the following macro `m`:
|
||||
|
||||
```rust
|
||||
macro_rules! m {
|
||||
($a:expr, $b:expr) => {
|
||||
if $a.is_some() {
|
||||
$b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let x: Option<u32> = Some(42);
|
||||
m!(x, x.unwrap());
|
||||
```
|
||||
|
||||
If the `m!(x, x.unwrapp());` line is expanded, we would get two expanded
|
||||
expressions:
|
||||
|
||||
- `x.is_some()` (from the `$a.is_some()` line in the `m` macro)
|
||||
- `x.unwrap()` (corresponding to `$b` in the `m` macro)
|
||||
|
||||
Suppose `x.is_some()` expression's span is associated with the `x_is_some_span` variable
|
||||
and `x.unwrap()` expression's span is associated with `x_unwrap_span` variable,
|
||||
we could assume that these two spans do not share the same context:
|
||||
|
||||
```rust
|
||||
// x.is_some() is from inside the macro
|
||||
// x.unwrap() is from outside the macro
|
||||
assert_ne!(x_is_some_span.ctxt(), x_unwrap_span.ctxt());
|
||||
```
|
||||
|
||||
### The `in_external_macro` function
|
||||
|
||||
`rustc_middle::lint` provides a function ([`in_external_macro`]) that can
|
||||
detect if the given span is from a macro defined in a foreign crate.
|
||||
|
||||
Therefore, if we really want a new lint to work with macro-generated code,
|
||||
this is the next line of defense to avoid macros not defined inside
|
||||
the current crate since it is unfair to the user if Clippy lints code
|
||||
which the user cannot change.
|
||||
|
||||
For example, assume we have the following code that is being examined
|
||||
by Clippy:
|
||||
|
||||
```rust
|
||||
#[macro_use]
|
||||
extern crate a_foreign_crate_with_macros;
|
||||
|
||||
// `foo` macro is defined in `a_foreign_crate_with_macros`
|
||||
foo!("bar");
|
||||
```
|
||||
|
||||
Also assume that we get the corresponding variable `foo_span` for the
|
||||
`foo` macro call, we could decide not to lint if `in_external_macro`
|
||||
results in `true` (note that `cx` can be `EarlyContext` or `LateContext`):
|
||||
|
||||
```rust
|
||||
if in_external_macro(cx.sess(), foo_span) {
|
||||
// We should ignore macro from a foreign crate.
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
[`ctxt`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.ctxt
|
||||
[expansion]: https://rustc-dev-guide.rust-lang.org/macro-expansion.html#expansion-and-ast-integration
|
||||
[`from_expansion`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.from_expansion
|
||||
[`in_external_macro`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_middle/lint/fn.in_external_macro.html
|
||||
[Span]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html
|
||||
[SpanContext]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/hygiene/struct.SyntaxContext.html
|
@ -51,7 +51,7 @@ impl LateLintPass<'_> for MyStructLint {
|
||||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||
// Get type of `expr`
|
||||
let ty = cx.typeck_results().expr_ty(expr);
|
||||
|
||||
|
||||
// Check if the `Ty` of this expression is of character type
|
||||
if ty.is_char() {
|
||||
println!("Our expression is a char!");
|
||||
@ -70,18 +70,18 @@ pub fn is_char(self) -> bool {
|
||||
}
|
||||
```
|
||||
|
||||
Indeed, we just discovered `Ty`'s [`kind` method][kind], which provides us
|
||||
Indeed, we just discovered `Ty`'s [`kind()` method][kind], which provides us
|
||||
with [`TyKind`][TyKind] of a `Ty`.
|
||||
|
||||
## `TyKind`
|
||||
|
||||
`TyKind` defines the kinds of types in Rust's type system.
|
||||
Peeking into [`TyKind` documentation][TyKind], we will see that it is an
|
||||
enum of 27 variants, including items such as `Bool`, `Int`, `Ref`, etc.
|
||||
enum of over 25 variants, including items such as `Bool`, `Int`, `Ref`, etc.
|
||||
|
||||
### `kind` Usage
|
||||
|
||||
The `TyKind` of `Ty` can be returned by calling [`Ty.kind` method][kind].
|
||||
The `TyKind` of `Ty` can be returned by calling [`Ty.kind()` method][kind].
|
||||
We often use this method to perform pattern matching in Clippy.
|
||||
|
||||
For instance, if we want to check for a `struct`, we could examine if the
|
||||
@ -107,15 +107,21 @@ impl LateLintPass<'_> for MyStructLint {
|
||||
We've been talking about [`ty::Ty`][middle_ty] this whole time without addressing [`hir::Ty`][hir_ty], but the latter
|
||||
is also important to understand.
|
||||
|
||||
`hir::Ty` would represent *what* an user wrote, while `ty::Ty` would understand the meaning of it (because it has more
|
||||
information).
|
||||
`hir::Ty` would represent *what* the user wrote, while `ty::Ty` is how the compiler sees the type and has more
|
||||
information. Example:
|
||||
|
||||
**Example: `fn foo(x: u32) -> u32 { x }`**
|
||||
```rust
|
||||
fn foo(x: u32) -> u32 { x }
|
||||
```
|
||||
|
||||
Here the HIR sees the types without "thinking" about them, it knows that the function takes an `u32` and returns
|
||||
an `u32`. But at the `ty::Ty` level the compiler understands that they're the same type, in-depth lifetimes, etc...
|
||||
an `u32`. As far as `hir::Ty` is concerned those might be different types. But at the `ty::Ty` level the compiler
|
||||
understands that they're the same type, in-depth lifetimes, etc...
|
||||
|
||||
you can use the [`hir_ty_to_ty`][hir_ty_to_ty] function to convert from a `hir::Ty` to a `ty::Ty`
|
||||
To get from a `hir::Ty` to a `ty::Ty`, you can use the [`hir_ty_to_ty`][hir_ty_to_ty] function outside of bodies or
|
||||
outside of bodies the [`TypeckResults::node_type()`][node_type] method.
|
||||
|
||||
> **Warning**: Don't use `hir_ty_to_ty` inside of bodies, because this can cause ICEs.
|
||||
|
||||
## Useful Links
|
||||
|
||||
@ -130,6 +136,7 @@ in this chapter:
|
||||
[Adt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variant.Adt
|
||||
[AdtDef]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/adt/struct.AdtDef.html
|
||||
[expr_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html#method.expr_ty
|
||||
[node_type]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html#method.node_type
|
||||
[is_char]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html#method.is_char
|
||||
[is_char_source]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_middle/ty/sty.rs.html#1831-1834
|
||||
[kind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html#method.kind
|
||||
|
@ -55,6 +55,7 @@ Please use that command to update the file and do not edit it by hand.
|
||||
| [suppress-restriction-lint-in-const](#suppress-restriction-lint-in-const) | `false` |
|
||||
| [missing-docs-in-crate-items](#missing-docs-in-crate-items) | `false` |
|
||||
| [future-size-threshold](#future-size-threshold) | `16384` |
|
||||
| [unnecessary-box-size](#unnecessary-box-size) | `128` |
|
||||
|
||||
### arithmetic-side-effects-allowed
|
||||
Suppress checking of the passed type names in all types of operations.
|
||||
@ -561,4 +562,12 @@ The maximum byte size a `Future` can have, before it triggers the `clippy::large
|
||||
* [large_futures](https://rust-lang.github.io/rust-clippy/master/index.html#large_futures)
|
||||
|
||||
|
||||
### unnecessary-box-size
|
||||
The byte size a `T` in `Box<T>` can have, below which it triggers the `clippy::unnecessary_box` lint
|
||||
|
||||
**Default Value:** `128` (`u64`)
|
||||
|
||||
* [unnecessary_box_returns](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns)
|
||||
|
||||
|
||||
|
||||
|
@ -741,7 +741,7 @@ fn gen_deprecated_lints_test(lints: &[DeprecatedLint]) -> String {
|
||||
fn gen_renamed_lints_test(lints: &[RenamedLint]) -> String {
|
||||
let mut seen_lints = HashSet::new();
|
||||
let mut res: String = GENERATED_FILE_COMMENT.into();
|
||||
res.push_str("// run-rustfix\n\n");
|
||||
res.push_str("//@run-rustfix\n\n");
|
||||
for lint in lints {
|
||||
if seen_lints.insert(&lint.new_name) {
|
||||
writeln!(res, "#![allow({})]", lint.new_name).unwrap();
|
||||
|
@ -6,7 +6,7 @@ use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// Detects uses of the `#[allow]` attribute and suggests replacing it with
|
||||
/// Checks for usage of the `#[allow]` attribute and suggests replacing it with
|
||||
/// the `#[expect]` (See [RFC 2383](https://rust-lang.github.io/rfcs/2383-lint-reasons.html))
|
||||
///
|
||||
/// The expect attribute is still unstable and requires the `lint_reasons`
|
||||
|
@ -506,7 +506,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for uses of the `abs()` method that cast the result to unsigned.
|
||||
/// Checks for usage of the `abs()` method that cast the result to unsigned.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// The `unsigned_abs()` method avoids panic when called on the MIN value.
|
||||
@ -625,14 +625,14 @@ declare_clippy_lint! {
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let string = String::with_capacity(1);
|
||||
/// let ptr = string.as_ptr() as *mut u8;
|
||||
/// let mut vec = Vec::<u8>::with_capacity(1);
|
||||
/// let ptr = vec.as_ptr() as *mut u8;
|
||||
/// unsafe { ptr.write(4) }; // UNDEFINED BEHAVIOUR
|
||||
/// ```
|
||||
/// Use instead:
|
||||
/// ```rust
|
||||
/// let mut string = String::with_capacity(1);
|
||||
/// let ptr = string.as_mut_ptr();
|
||||
/// let mut vec = Vec::<u8>::with_capacity(1);
|
||||
/// let ptr = vec.as_mut_ptr();
|
||||
/// unsafe { ptr.write(4) };
|
||||
/// ```
|
||||
#[clippy::version = "1.66.0"]
|
||||
|
@ -9,7 +9,7 @@ use rustc_span::{symbol::sym, Span};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for use of `crate` as opposed to `$crate` in a macro definition.
|
||||
/// Checks for usage of `crate` as opposed to `$crate` in a macro definition.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// `crate` refers to the macro call's crate, whereas `$crate` refers to the macro definition's
|
||||
|
@ -215,6 +215,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
|
||||
crate::invalid_upcast_comparisons::INVALID_UPCAST_COMPARISONS_INFO,
|
||||
crate::invalid_utf8_in_unchecked::INVALID_UTF8_IN_UNCHECKED_INFO,
|
||||
crate::items_after_statements::ITEMS_AFTER_STATEMENTS_INFO,
|
||||
crate::items_after_test_module::ITEMS_AFTER_TEST_MODULE_INFO,
|
||||
crate::iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR_INFO,
|
||||
crate::large_const_arrays::LARGE_CONST_ARRAYS_INFO,
|
||||
crate::large_enum_variant::LARGE_ENUM_VARIANT_INFO,
|
||||
|
@ -19,7 +19,7 @@ use rustc_span::{Span, SyntaxContext, DUMMY_SP};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for uses of `contains_key` + `insert` on `HashMap`
|
||||
/// Checks for usage of `contains_key` + `insert` on `HashMap`
|
||||
/// or `BTreeMap`.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! lint on enum variants that are prefixed or suffixed by the same characters
|
||||
|
||||
use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
|
||||
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_hir};
|
||||
use clippy_utils::source::is_present_in_source;
|
||||
use clippy_utils::str_utils::{camel_case_split, count_match_end, count_match_start};
|
||||
use rustc_hir::{EnumDef, Item, ItemKind, Variant};
|
||||
@ -135,9 +135,10 @@ fn check_enum_start(cx: &LateContext<'_>, item_name: &str, variant: &Variant<'_>
|
||||
&& name.chars().nth(item_name_chars).map_or(false, |c| !c.is_lowercase())
|
||||
&& name.chars().nth(item_name_chars + 1).map_or(false, |c| !c.is_numeric())
|
||||
{
|
||||
span_lint(
|
||||
span_lint_hir(
|
||||
cx,
|
||||
ENUM_VARIANT_NAMES,
|
||||
variant.hir_id,
|
||||
variant.span,
|
||||
"variant name starts with the enum's name",
|
||||
);
|
||||
@ -149,9 +150,10 @@ fn check_enum_end(cx: &LateContext<'_>, item_name: &str, variant: &Variant<'_>)
|
||||
let item_name_chars = item_name.chars().count();
|
||||
|
||||
if count_match_end(item_name, name).char_count == item_name_chars {
|
||||
span_lint(
|
||||
span_lint_hir(
|
||||
cx,
|
||||
ENUM_VARIANT_NAMES,
|
||||
variant.hir_id,
|
||||
variant.span,
|
||||
"variant name ends with the enum's name",
|
||||
);
|
||||
|
@ -51,7 +51,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for use of `println`, `print`, `eprintln` or `eprint` in an
|
||||
/// Checks for usage of `println`, `print`, `eprintln` or `eprint` in an
|
||||
/// implementation of a formatting trait.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
|
@ -10,7 +10,7 @@ use rustc_span::source_map::Span;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for use of the non-existent `=*`, `=!` and `=-`
|
||||
/// Checks for usage of the non-existent `=*`, `=!` and `=-`
|
||||
/// operators.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
|
@ -348,7 +348,7 @@ declare_clippy_lint! {
|
||||
/// // [...]
|
||||
/// }
|
||||
/// ```
|
||||
#[clippy::version = "1.68.0"]
|
||||
#[clippy::version = "1.69.0"]
|
||||
pub IMPL_TRAIT_IN_PARAMS,
|
||||
restriction,
|
||||
"`impl Trait` is used in the function's parameters"
|
||||
|
83
clippy_lints/src/items_after_test_module.rs
Normal file
83
clippy_lints/src/items_after_test_module.rs
Normal file
@ -0,0 +1,83 @@
|
||||
use clippy_utils::{diagnostics::span_lint_and_help, is_in_cfg_test};
|
||||
use rustc_hir::{HirId, ItemId, ItemKind, Mod};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::{sym, Span};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Triggers if an item is declared after the testing module marked with `#[cfg(test)]`.
|
||||
/// ### Why is this bad?
|
||||
/// Having items declared after the testing module is confusing and may lead to bad test coverage.
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// #[cfg(test)]
|
||||
/// mod tests {
|
||||
/// // [...]
|
||||
/// }
|
||||
///
|
||||
/// fn my_function() {
|
||||
/// // [...]
|
||||
/// }
|
||||
/// ```
|
||||
/// Use instead:
|
||||
/// ```rust
|
||||
/// fn my_function() {
|
||||
/// // [...]
|
||||
/// }
|
||||
///
|
||||
/// #[cfg(test)]
|
||||
/// mod tests {
|
||||
/// // [...]
|
||||
/// }
|
||||
/// ```
|
||||
#[clippy::version = "1.70.0"]
|
||||
pub ITEMS_AFTER_TEST_MODULE,
|
||||
style,
|
||||
"An item was found after the testing module `tests`"
|
||||
}
|
||||
|
||||
declare_lint_pass!(ItemsAfterTestModule => [ITEMS_AFTER_TEST_MODULE]);
|
||||
|
||||
impl LateLintPass<'_> for ItemsAfterTestModule {
|
||||
fn check_mod(&mut self, cx: &LateContext<'_>, _: &Mod<'_>, _: HirId) {
|
||||
let mut was_test_mod_visited = false;
|
||||
let mut test_mod_span: Option<Span> = None;
|
||||
|
||||
let hir = cx.tcx.hir();
|
||||
let items = hir.items().collect::<Vec<ItemId>>();
|
||||
|
||||
for (i, itid) in items.iter().enumerate() {
|
||||
let item = hir.item(*itid);
|
||||
|
||||
if_chain! {
|
||||
if was_test_mod_visited;
|
||||
if i == (items.len() - 3 /* Weird magic number (HIR-translation behaviour) */);
|
||||
if cx.sess().source_map().lookup_char_pos(item.span.lo()).file.name_hash
|
||||
== cx.sess().source_map().lookup_char_pos(test_mod_span.unwrap().lo()).file.name_hash; // Will never fail
|
||||
if !matches!(item.kind, ItemKind::Mod(_));
|
||||
if !is_in_cfg_test(cx.tcx, itid.hir_id()); // The item isn't in the testing module itself
|
||||
if !in_external_macro(cx.sess(), item.span);
|
||||
|
||||
then {
|
||||
span_lint_and_help(cx, ITEMS_AFTER_TEST_MODULE, test_mod_span.unwrap().with_hi(item.span.hi()), "items were found after the testing module", None, "move the items to before the testing module was defined");
|
||||
}};
|
||||
|
||||
if matches!(item.kind, ItemKind::Mod(_)) {
|
||||
for attr in cx.tcx.get_attrs(item.owner_id.to_def_id(), sym::cfg) {
|
||||
if_chain! {
|
||||
if attr.has_name(sym::cfg);
|
||||
if let Some(mitems) = attr.meta_item_list();
|
||||
if let [mitem] = &*mitems;
|
||||
if mitem.has_name(sym::test);
|
||||
then {
|
||||
was_test_mod_visited = true;
|
||||
test_mod_span = Some(item.span);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -168,25 +168,27 @@ impl<'tcx> LateLintPass<'tcx> for LenZero {
|
||||
}
|
||||
|
||||
if let ExprKind::Binary(Spanned { node: cmp, .. }, left, right) = expr.kind {
|
||||
// expr.span might contains parenthesis, see issue #10529
|
||||
let actual_span = left.span.with_hi(right.span.hi());
|
||||
match cmp {
|
||||
BinOpKind::Eq => {
|
||||
check_cmp(cx, expr.span, left, right, "", 0); // len == 0
|
||||
check_cmp(cx, expr.span, right, left, "", 0); // 0 == len
|
||||
check_cmp(cx, actual_span, left, right, "", 0); // len == 0
|
||||
check_cmp(cx, actual_span, right, left, "", 0); // 0 == len
|
||||
},
|
||||
BinOpKind::Ne => {
|
||||
check_cmp(cx, expr.span, left, right, "!", 0); // len != 0
|
||||
check_cmp(cx, expr.span, right, left, "!", 0); // 0 != len
|
||||
check_cmp(cx, actual_span, left, right, "!", 0); // len != 0
|
||||
check_cmp(cx, actual_span, right, left, "!", 0); // 0 != len
|
||||
},
|
||||
BinOpKind::Gt => {
|
||||
check_cmp(cx, expr.span, left, right, "!", 0); // len > 0
|
||||
check_cmp(cx, expr.span, right, left, "", 1); // 1 > len
|
||||
check_cmp(cx, actual_span, left, right, "!", 0); // len > 0
|
||||
check_cmp(cx, actual_span, right, left, "", 1); // 1 > len
|
||||
},
|
||||
BinOpKind::Lt => {
|
||||
check_cmp(cx, expr.span, left, right, "", 1); // len < 1
|
||||
check_cmp(cx, expr.span, right, left, "!", 0); // 0 < len
|
||||
check_cmp(cx, actual_span, left, right, "", 1); // len < 1
|
||||
check_cmp(cx, actual_span, right, left, "!", 0); // 0 < len
|
||||
},
|
||||
BinOpKind::Ge => check_cmp(cx, expr.span, left, right, "!", 1), // len >= 1
|
||||
BinOpKind::Le => check_cmp(cx, expr.span, right, left, "!", 1), // 1 <= len
|
||||
BinOpKind::Ge => check_cmp(cx, actual_span, left, right, "!", 1), // len >= 1
|
||||
BinOpKind::Le => check_cmp(cx, actual_span, right, left, "!", 1), // 1 <= len
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::ty::{implements_trait, is_must_use_ty, match_type};
|
||||
use clippy_utils::{is_must_use_func_call, paths};
|
||||
use rustc_hir::{Local, PatKind};
|
||||
use rustc_hir::{ExprKind, Local, PatKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::ty::subst::GenericArgKind;
|
||||
@ -189,7 +189,18 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
|
||||
|
||||
if local.pat.default_binding_modes && local.ty.is_none() {
|
||||
// When `default_binding_modes` is true, the `let` keyword is present.
|
||||
span_lint_and_help(
|
||||
|
||||
// Ignore function calls that return impl traits...
|
||||
if let Some(init) = local.init &&
|
||||
matches!(init.kind, ExprKind::Call(_, _) | ExprKind::MethodCall(_, _, _, _)) {
|
||||
let expr_ty = cx.typeck_results().expr_ty(init);
|
||||
if expr_ty.is_impl_trait() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
LET_UNDERSCORE_UNTYPED,
|
||||
local.span,
|
||||
|
@ -158,6 +158,7 @@ mod int_plus_one;
|
||||
mod invalid_upcast_comparisons;
|
||||
mod invalid_utf8_in_unchecked;
|
||||
mod items_after_statements;
|
||||
mod items_after_test_module;
|
||||
mod iter_not_returning_iterator;
|
||||
mod large_const_arrays;
|
||||
mod large_enum_variant;
|
||||
@ -950,15 +951,18 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
||||
store.register_late_pass(|_| Box::new(allow_attributes::AllowAttribute));
|
||||
store.register_late_pass(move |_| Box::new(manual_main_separator_str::ManualMainSeparatorStr::new(msrv())));
|
||||
store.register_late_pass(|_| Box::new(unnecessary_struct_initialization::UnnecessaryStruct));
|
||||
let unnecessary_box_size = conf.unnecessary_box_size;
|
||||
store.register_late_pass(move |_| {
|
||||
Box::new(unnecessary_box_returns::UnnecessaryBoxReturns::new(
|
||||
avoid_breaking_exported_api,
|
||||
unnecessary_box_size,
|
||||
))
|
||||
});
|
||||
store.register_late_pass(|_| Box::new(lines_filter_map_ok::LinesFilterMapOk));
|
||||
store.register_late_pass(|_| Box::new(tests_outside_test_module::TestsOutsideTestModule));
|
||||
store.register_late_pass(|_| Box::new(manual_slice_size_calculation::ManualSliceSizeCalculation));
|
||||
store.register_early_pass(|| Box::new(suspicious_doc_comments::SuspiciousDocComments));
|
||||
store.register_late_pass(|_| Box::new(items_after_test_module::ItemsAfterTestModule));
|
||||
// add lints here, do not remove this comment, it's used in `new_lint`
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ use rustc_span::sym;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Detect uses of `lines.filter_map(Result::ok)` or `lines.flat_map(Result::ok)`
|
||||
/// Checks for usage of `lines.filter_map(Result::ok)` or `lines.flat_map(Result::ok)`
|
||||
/// when `lines` has type `std::io::Lines`.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
|
@ -13,7 +13,7 @@ use rustc_span::sym;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for uses of `std::mem::size_of::<T>() * 8` when
|
||||
/// Checks for usage of `std::mem::size_of::<T>() * 8` when
|
||||
/// `T::BITS` is available.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
|
@ -1,5 +1,7 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::{expr_or_init, in_constant};
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::snippet_with_context;
|
||||
use clippy_utils::{expr_or_init, in_constant, std_or_core};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BinOpKind, Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty;
|
||||
@ -38,19 +40,27 @@ declare_lint_pass!(ManualSliceSizeCalculation => [MANUAL_SLICE_SIZE_CALCULATION]
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for ManualSliceSizeCalculation {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
||||
// Does not apply inside const because size_of_value is not cost in stable.
|
||||
// Does not apply inside const because size_of_val is not cost in stable.
|
||||
if !in_constant(cx, expr.hir_id)
|
||||
&& let ExprKind::Binary(ref op, left, right) = expr.kind
|
||||
&& BinOpKind::Mul == op.node
|
||||
&& let Some(_receiver) = simplify(cx, left, right)
|
||||
&& !expr.span.from_expansion()
|
||||
&& let Some(receiver) = simplify(cx, left, right)
|
||||
{
|
||||
span_lint_and_help(
|
||||
let ctxt = expr.span.ctxt();
|
||||
let mut app = Applicability::MachineApplicable;
|
||||
let val_name = snippet_with_context(cx, receiver.span, ctxt, "slice", &mut app).0;
|
||||
let Some(sugg) = std_or_core(cx) else { return };
|
||||
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
MANUAL_SLICE_SIZE_CALCULATION,
|
||||
expr.span,
|
||||
"manual slice size calculation",
|
||||
None,
|
||||
"consider using std::mem::size_of_value instead");
|
||||
"try",
|
||||
format!("{sugg}::mem::size_of_val({val_name})"),
|
||||
app,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -71,9 +81,9 @@ fn simplify_half<'tcx>(
|
||||
expr1: &'tcx Expr<'tcx>,
|
||||
expr2: &'tcx Expr<'tcx>,
|
||||
) -> Option<&'tcx Expr<'tcx>> {
|
||||
if
|
||||
if !expr1.span.from_expansion()
|
||||
// expr1 is `[T1].len()`?
|
||||
let ExprKind::MethodCall(method_path, receiver, _, _) = expr1.kind
|
||||
&& let ExprKind::MethodCall(method_path, receiver, _, _) = expr1.kind
|
||||
&& method_path.ident.name == sym::len
|
||||
&& let receiver_ty = cx.typeck_results().expr_ty(receiver)
|
||||
&& let ty::Slice(ty1) = receiver_ty.peel_refs().kind()
|
||||
|
@ -843,7 +843,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for usages of `Err(x)?`.
|
||||
/// Checks for usage of `Err(x)?`.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// The `?` operator is designed to allow calls that
|
||||
@ -878,7 +878,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for usages of `match` which could be implemented using `map`
|
||||
/// Checks for usage of `match` which could be implemented using `map`
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// Using the `map` method is clearer and more concise.
|
||||
@ -902,7 +902,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for usages of `match` which could be implemented using `filter`
|
||||
/// Checks for usage of `match` which could be implemented using `filter`
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// Using the `filter` method is clearer and more concise.
|
||||
|
@ -121,7 +121,7 @@ use rustc_span::{sym, Span};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for usages of `cloned()` on an `Iterator` or `Option` where
|
||||
/// Checks for usage of `cloned()` on an `Iterator` or `Option` where
|
||||
/// `copied()` could be used instead.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
@ -201,7 +201,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for usages of `Iterator::flat_map()` where `filter_map()` could be
|
||||
/// Checks for usage of `Iterator::flat_map()` where `filter_map()` could be
|
||||
/// used instead.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
@ -441,7 +441,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for usages of `_.unwrap_or_else(Default::default)` on `Option` and
|
||||
/// Checks for usage of `_.unwrap_or_else(Default::default)` on `Option` and
|
||||
/// `Result` values.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
@ -1194,7 +1194,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for use of `.iter().nth()` (and the related
|
||||
/// Checks for usage of `.iter().nth()` (and the related
|
||||
/// `.iter_mut().nth()`) on standard library types with *O*(1) element access.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
@ -1221,7 +1221,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for use of `.skip(x).next()` on iterators.
|
||||
/// Checks for usage of `.skip(x).next()` on iterators.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// `.nth(x)` is cleaner
|
||||
@ -1246,7 +1246,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for use of `.drain(..)` on `Vec` and `VecDeque` for iteration.
|
||||
/// Checks for usage of `.drain(..)` on `Vec` and `VecDeque` for iteration.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// `.into_iter()` is simpler with better performance.
|
||||
@ -1271,7 +1271,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for using `x.get(x.len() - 1)` instead of
|
||||
/// Checks for usage of `x.get(x.len() - 1)` instead of
|
||||
/// `x.last()`.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
@ -1304,7 +1304,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for use of `.get().unwrap()` (or
|
||||
/// Checks for usage of `.get().unwrap()` (or
|
||||
/// `.get_mut().unwrap`) on a standard library type which implements `Index`
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
@ -1475,7 +1475,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for using `fold` when a more succinct alternative exists.
|
||||
/// Checks for usage of `fold` when a more succinct alternative exists.
|
||||
/// Specifically, this checks for `fold`s which could be replaced by `any`, `all`,
|
||||
/// `sum` or `product`.
|
||||
///
|
||||
@ -2161,7 +2161,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for usages of `str::splitn(2, _)`
|
||||
/// Checks for usage of `str::splitn(2, _)`
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// `split_once` is both clearer in intent and slightly more efficient.
|
||||
@ -2197,7 +2197,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for usages of `str::splitn` (or `str::rsplitn`) where using `str::split` would be the same.
|
||||
/// Checks for usage of `str::splitn` (or `str::rsplitn`) where using `str::split` would be the same.
|
||||
/// ### Why is this bad?
|
||||
/// The function `split` is simpler and there is no performance difference in these cases, considering
|
||||
/// that both functions return a lazy iterator.
|
||||
@ -2251,7 +2251,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for use of `.collect::<Vec<String>>().join("")` on iterators.
|
||||
/// Checks for usage of `.collect::<Vec<String>>().join("")` on iterators.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// `.collect::<String>()` is more concise and might be more performant
|
||||
@ -2377,7 +2377,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for usages of `.then_some(..).unwrap_or(..)`
|
||||
/// Checks for usage of `.then_some(..).unwrap_or(..)`
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// This can be written more clearly with `if .. else ..`
|
||||
@ -2553,7 +2553,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for using `x.get(0)` instead of
|
||||
/// Checks for usage of `x.get(0)` instead of
|
||||
/// `x.first()`.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
@ -2957,7 +2957,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Detects uses of `Vec::sort_by` passing in a closure
|
||||
/// Checks for usage of `Vec::sort_by` passing in a closure
|
||||
/// which compares the two arguments, either directly or indirectly.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
@ -3013,7 +3013,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for use of File::read_to_end and File::read_to_string.
|
||||
/// Checks for usage of File::read_to_end and File::read_to_string.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// `fs::{read, read_to_string}` provide the same functionality when `buf` is empty with fewer imports and no intermediate values.
|
||||
@ -3185,7 +3185,7 @@ declare_clippy_lint! {
|
||||
/// ```rust
|
||||
/// std::process::Command::new("echo").args(["-n", "hello"]).spawn().unwrap();
|
||||
/// ```
|
||||
#[clippy::version = "1.67.0"]
|
||||
#[clippy::version = "1.69.0"]
|
||||
pub SUSPICIOUS_COMMAND_ARG_SPACE,
|
||||
suspicious,
|
||||
"single command line argument that looks like it should be multiple arguments"
|
||||
|
@ -1,5 +1,3 @@
|
||||
// run-rustfix
|
||||
|
||||
use super::OBFUSCATED_IF_ELSE;
|
||||
use clippy_utils::{diagnostics::span_lint_and_sugg, source::snippet_with_applicability};
|
||||
use rustc_errors::Applicability;
|
||||
|
@ -59,7 +59,7 @@ declare_clippy_lint! {
|
||||
/// unsafe { char::from_u32_unchecked(int_value) }
|
||||
/// }
|
||||
/// ```
|
||||
#[clippy::version = "1.68.0"]
|
||||
#[clippy::version = "1.69.0"]
|
||||
pub MULTIPLE_UNSAFE_OPS_PER_BLOCK,
|
||||
restriction,
|
||||
"more than one unsafe operation per `unsafe` block"
|
||||
|
@ -1,4 +1,4 @@
|
||||
//! Checks for uses of mutex where an atomic value could be used
|
||||
//! Checks for usage of mutex where an atomic value could be used
|
||||
//!
|
||||
//! This lint is **allow** by default
|
||||
|
||||
@ -12,7 +12,7 @@ use rustc_span::sym;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for usages of `Mutex<X>` where an atomic will do.
|
||||
/// Checks for usage of `Mutex<X>` where an atomic will do.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// Using a mutex just to make access to a plain bool or
|
||||
@ -49,7 +49,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for usages of `Mutex<X>` where `X` is an integral
|
||||
/// Checks for usage of `Mutex<X>` where `X` is an integral
|
||||
/// type.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
|
@ -1,4 +1,4 @@
|
||||
//! Checks for uses of const which the type is not `Freeze` (`Cell`-free).
|
||||
//! Checks for usage of const which the type is not `Freeze` (`Cell`-free).
|
||||
//!
|
||||
//! This lint is **warn** by default.
|
||||
|
||||
|
@ -76,8 +76,8 @@ fn check_lit(cx: &EarlyContext<'_>, lit: &Lit, span: Span, is_string: bool) {
|
||||
if ch == '\\' {
|
||||
if let Some((_, '0')) = iter.next() {
|
||||
// collect up to two further octal digits
|
||||
if let Some((mut to, '0'..='7')) = iter.next() {
|
||||
if let Some((_, '0'..='7')) = iter.peek() {
|
||||
if let Some((mut to, _)) = iter.next_if(|(_, ch)| matches!(ch, '0'..='7')) {
|
||||
if iter.next_if(|(_, ch)| matches!(ch, '0'..='7')).is_some() {
|
||||
to += 1;
|
||||
}
|
||||
found.push((from, to + 1));
|
||||
@ -90,32 +90,6 @@ fn check_lit(cx: &EarlyContext<'_>, lit: &Lit, span: Span, is_string: bool) {
|
||||
return;
|
||||
}
|
||||
|
||||
// construct two suggestion strings, one with \x escapes with octal meaning
|
||||
// as in C, and one with \x00 for null bytes.
|
||||
let mut suggest_1 = if is_string { "\"" } else { "b\"" }.to_string();
|
||||
let mut suggest_2 = suggest_1.clone();
|
||||
let mut index = 0;
|
||||
for (from, to) in found {
|
||||
suggest_1.push_str(&contents[index..from]);
|
||||
suggest_2.push_str(&contents[index..from]);
|
||||
|
||||
// construct a replacement escape
|
||||
// the maximum value is \077, or \x3f, so u8 is sufficient here
|
||||
if let Ok(n) = u8::from_str_radix(&contents[from + 1..to], 8) {
|
||||
write!(suggest_1, "\\x{n:02x}").unwrap();
|
||||
}
|
||||
|
||||
// append the null byte as \x00 and the following digits literally
|
||||
suggest_2.push_str("\\x00");
|
||||
suggest_2.push_str(&contents[from + 2..to]);
|
||||
|
||||
index = to;
|
||||
}
|
||||
suggest_1.push_str(&contents[index..]);
|
||||
suggest_1.push('"');
|
||||
suggest_2.push_str(&contents[index..]);
|
||||
suggest_2.push('"');
|
||||
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
OCTAL_ESCAPES,
|
||||
@ -129,23 +103,53 @@ fn check_lit(cx: &EarlyContext<'_>, lit: &Lit, span: Span, is_string: bool) {
|
||||
"octal escapes are not supported, `\\0` is always a null {}",
|
||||
if is_string { "character" } else { "byte" }
|
||||
));
|
||||
// suggestion 1: equivalent hex escape
|
||||
diag.span_suggestion(
|
||||
span,
|
||||
"if an octal escape was intended, use the hexadecimal representation instead",
|
||||
suggest_1,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
// suggestion 2: unambiguous null byte
|
||||
diag.span_suggestion(
|
||||
span,
|
||||
format!(
|
||||
"if the null {} is intended, disambiguate using",
|
||||
if is_string { "character" } else { "byte" }
|
||||
),
|
||||
suggest_2,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
|
||||
// Generate suggestions if the string is not too long (~ 5 lines)
|
||||
if contents.len() < 400 {
|
||||
// construct two suggestion strings, one with \x escapes with octal meaning
|
||||
// as in C, and one with \x00 for null bytes.
|
||||
let mut suggest_1 = if is_string { "\"" } else { "b\"" }.to_string();
|
||||
let mut suggest_2 = suggest_1.clone();
|
||||
let mut index = 0;
|
||||
for (from, to) in found {
|
||||
suggest_1.push_str(&contents[index..from]);
|
||||
suggest_2.push_str(&contents[index..from]);
|
||||
|
||||
// construct a replacement escape
|
||||
// the maximum value is \077, or \x3f, so u8 is sufficient here
|
||||
if let Ok(n) = u8::from_str_radix(&contents[from + 1..to], 8) {
|
||||
write!(suggest_1, "\\x{n:02x}").unwrap();
|
||||
}
|
||||
|
||||
// append the null byte as \x00 and the following digits literally
|
||||
suggest_2.push_str("\\x00");
|
||||
suggest_2.push_str(&contents[from + 2..to]);
|
||||
|
||||
index = to;
|
||||
}
|
||||
suggest_1.push_str(&contents[index..]);
|
||||
suggest_2.push_str(&contents[index..]);
|
||||
|
||||
suggest_1.push('"');
|
||||
suggest_2.push('"');
|
||||
// suggestion 1: equivalent hex escape
|
||||
diag.span_suggestion(
|
||||
span,
|
||||
"if an octal escape was intended, use the hexadecimal representation instead",
|
||||
suggest_1,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
// suggestion 2: unambiguous null byte
|
||||
diag.span_suggestion(
|
||||
span,
|
||||
format!(
|
||||
"if the null {} is intended, disambiguate using",
|
||||
if is_string { "character" } else { "byte" }
|
||||
),
|
||||
suggest_2,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use super::ARITHMETIC_SIDE_EFFECTS;
|
||||
use clippy_utils::is_from_proc_macro;
|
||||
use clippy_utils::{
|
||||
consts::{constant, constant_simple, Constant},
|
||||
diagnostics::span_lint,
|
||||
@ -10,7 +11,10 @@ use rustc_hir as hir;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_session::impl_lint_pass;
|
||||
use rustc_span::source_map::{Span, Spanned};
|
||||
use rustc_span::{
|
||||
source_map::{Span, Spanned},
|
||||
Symbol,
|
||||
};
|
||||
|
||||
const HARD_CODED_ALLOWED_BINARY: &[[&str; 2]] = &[
|
||||
["f32", "f32"],
|
||||
@ -20,6 +24,7 @@ const HARD_CODED_ALLOWED_BINARY: &[[&str; 2]] = &[
|
||||
["std::string::String", "&str"],
|
||||
];
|
||||
const HARD_CODED_ALLOWED_UNARY: &[&str] = &["f32", "f64", "std::num::Saturating", "std::num::Wrapping"];
|
||||
const INTEGER_METHODS: &[&str] = &["saturating_div", "wrapping_div", "wrapping_rem", "wrapping_rem_euclid"];
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ArithmeticSideEffects {
|
||||
@ -28,6 +33,7 @@ pub struct ArithmeticSideEffects {
|
||||
// Used to check whether expressions are constants, such as in enum discriminants and consts
|
||||
const_span: Option<Span>,
|
||||
expr_span: Option<Span>,
|
||||
integer_methods: FxHashSet<Symbol>,
|
||||
}
|
||||
|
||||
impl_lint_pass!(ArithmeticSideEffects => [ARITHMETIC_SIDE_EFFECTS]);
|
||||
@ -53,6 +59,7 @@ impl ArithmeticSideEffects {
|
||||
allowed_unary,
|
||||
const_span: None,
|
||||
expr_span: None,
|
||||
integer_methods: INTEGER_METHODS.iter().map(|el| Symbol::intern(el)).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,6 +191,33 @@ impl ArithmeticSideEffects {
|
||||
}
|
||||
}
|
||||
|
||||
/// There are some integer methods like `wrapping_div` that will panic depending on the
|
||||
/// provided input.
|
||||
fn manage_method_call<'tcx>(
|
||||
&mut self,
|
||||
args: &[hir::Expr<'tcx>],
|
||||
cx: &LateContext<'tcx>,
|
||||
ps: &hir::PathSegment<'tcx>,
|
||||
receiver: &hir::Expr<'tcx>,
|
||||
) {
|
||||
let Some(arg) = args.first() else { return; };
|
||||
if constant_simple(cx, cx.typeck_results(), receiver).is_some() {
|
||||
return;
|
||||
}
|
||||
let instance_ty = cx.typeck_results().expr_ty(receiver);
|
||||
if !Self::is_integral(instance_ty) {
|
||||
return;
|
||||
}
|
||||
if !self.integer_methods.contains(&ps.ident.name) {
|
||||
return;
|
||||
}
|
||||
let (actual_arg, _) = peel_hir_expr_refs(arg);
|
||||
match Self::literal_integer(cx, actual_arg) {
|
||||
None | Some(0) => self.issue_lint(cx, arg),
|
||||
Some(_) => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn manage_unary_ops<'tcx>(
|
||||
&mut self,
|
||||
cx: &LateContext<'tcx>,
|
||||
@ -206,8 +240,9 @@ impl ArithmeticSideEffects {
|
||||
self.issue_lint(cx, expr);
|
||||
}
|
||||
|
||||
fn should_skip_expr(&mut self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
|
||||
fn should_skip_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &hir::Expr<'tcx>) -> bool {
|
||||
is_lint_allowed(cx, ARITHMETIC_SIDE_EFFECTS, expr.hir_id)
|
||||
|| is_from_proc_macro(cx, expr)
|
||||
|| self.expr_span.is_some()
|
||||
|| self.const_span.map_or(false, |sp| sp.contains(expr.span))
|
||||
}
|
||||
@ -222,6 +257,9 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects {
|
||||
hir::ExprKind::AssignOp(op, lhs, rhs) | hir::ExprKind::Binary(op, lhs, rhs) => {
|
||||
self.manage_bin_ops(cx, expr, op, lhs, rhs);
|
||||
},
|
||||
hir::ExprKind::MethodCall(ps, receiver, args, _) => {
|
||||
self.manage_method_call(args, cx, ps, receiver);
|
||||
},
|
||||
hir::ExprKind::Unary(un_op, un_expr) => {
|
||||
self.manage_unary_ops(cx, expr, un_expr, *un_op);
|
||||
},
|
||||
|
@ -685,7 +685,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for uses of bitwise and/or operators between booleans, where performance may be improved by using
|
||||
/// Checks for usage of bitwise and/or operators between booleans, where performance may be improved by using
|
||||
/// a lazy and.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
|
@ -1,12 +1,12 @@
|
||||
use super::{FLOAT_ARITHMETIC, INTEGER_ARITHMETIC};
|
||||
use clippy_utils::consts::constant_simple;
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use clippy_utils::is_from_proc_macro;
|
||||
use clippy_utils::is_integer_literal;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::source_map::Span;
|
||||
|
||||
use super::{FLOAT_ARITHMETIC, INTEGER_ARITHMETIC};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Context {
|
||||
expr_id: Option<hir::HirId>,
|
||||
@ -47,6 +47,9 @@ impl Context {
|
||||
|
||||
let (l_ty, r_ty) = (cx.typeck_results().expr_ty(l), cx.typeck_results().expr_ty(r));
|
||||
if l_ty.peel_refs().is_integral() && r_ty.peel_refs().is_integral() {
|
||||
if is_from_proc_macro(cx, expr) {
|
||||
return;
|
||||
}
|
||||
match op {
|
||||
hir::BinOpKind::Div | hir::BinOpKind::Rem => match &r.kind {
|
||||
hir::ExprKind::Lit(_lit) => (),
|
||||
@ -79,6 +82,9 @@ impl Context {
|
||||
let ty = cx.typeck_results().expr_ty(arg);
|
||||
if constant_simple(cx, cx.typeck_results(), expr).is_none() {
|
||||
if ty.is_integral() {
|
||||
if is_from_proc_macro(cx, expr) {
|
||||
return;
|
||||
}
|
||||
span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected");
|
||||
self.expr_id = Some(expr.hir_id);
|
||||
} else if ty.is_floating_point() {
|
||||
|
@ -24,7 +24,7 @@ declare_clippy_lint! {
|
||||
/// ```ignore
|
||||
/// utility_macro!(expr);
|
||||
/// ```
|
||||
#[clippy::version = "pre 1.29.0"]
|
||||
#[clippy::version = "1.69.0"]
|
||||
pub QUESTION_MARK_USED,
|
||||
restriction,
|
||||
"complains if the question mark operator is used"
|
||||
|
@ -17,7 +17,7 @@ use rustc_span::{symbol::Ident, Span, DUMMY_SP};
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
///
|
||||
/// Searches for elements marked with `#[clippy::significant_drop]` that could be early
|
||||
/// Searches for elements marked with `#[clippy::has_significant_drop]` that could be early
|
||||
/// dropped but are in fact dropped at the end of their scopes. In other words, enforces the
|
||||
/// "tightening" of their possible lifetimes.
|
||||
///
|
||||
@ -46,7 +46,7 @@ declare_clippy_lint! {
|
||||
/// do_heavy_computation_that_takes_time(owned_rslt);
|
||||
/// }
|
||||
/// ```
|
||||
#[clippy::version = "1.67.0"]
|
||||
#[clippy::version = "1.69.0"]
|
||||
pub SIGNIFICANT_DROP_TIGHTENING,
|
||||
nursery,
|
||||
"Searches for elements marked with `#[clippy::has_significant_drop]` that could be early dropped but are in fact dropped at the end of their scopes"
|
||||
|
@ -22,7 +22,7 @@ use rustc_span::source_map::Span;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for use of `Box<T>` where T is a collection such as Vec anywhere in the code.
|
||||
/// Checks for usage of `Box<T>` where T is a collection such as Vec anywhere in the code.
|
||||
/// Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
@ -52,7 +52,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for use of `Vec<Box<T>>` where T: Sized anywhere in the code.
|
||||
/// Checks for usage of `Vec<Box<T>>` where T: Sized anywhere in the code.
|
||||
/// Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
@ -85,7 +85,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for use of `Option<Option<_>>` in function signatures and type
|
||||
/// Checks for usage of `Option<Option<_>>` in function signatures and type
|
||||
/// definitions
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
@ -164,7 +164,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for use of `&Box<T>` anywhere in the code.
|
||||
/// Checks for usage of `&Box<T>` anywhere in the code.
|
||||
/// Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
@ -190,7 +190,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for use of redundant allocations anywhere in the code.
|
||||
/// Checks for usage of redundant allocations anywhere in the code.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// Expressions such as `Rc<&T>`, `Rc<Rc<T>>`, `Rc<Arc<T>>`, `Rc<Box<T>>`, `Arc<&T>`, `Arc<Rc<T>>`,
|
||||
|
@ -1,4 +1,4 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::{diagnostics::span_lint_and_then, ty::approx_ty_size};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{def_id::LocalDefId, FnDecl, FnRetTy, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
@ -10,6 +10,9 @@ declare_clippy_lint! {
|
||||
///
|
||||
/// Checks for a return type containing a `Box<T>` where `T` implements `Sized`
|
||||
///
|
||||
/// The lint ignores `Box<T>` where `T` is larger than `unnecessary_box_size`,
|
||||
/// as returning a large `T` directly may be detrimental to performance.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
///
|
||||
/// It's better to just return `T` in these cases. The caller may not need
|
||||
@ -36,14 +39,16 @@ declare_clippy_lint! {
|
||||
|
||||
pub struct UnnecessaryBoxReturns {
|
||||
avoid_breaking_exported_api: bool,
|
||||
maximum_size: u64,
|
||||
}
|
||||
|
||||
impl_lint_pass!(UnnecessaryBoxReturns => [UNNECESSARY_BOX_RETURNS]);
|
||||
|
||||
impl UnnecessaryBoxReturns {
|
||||
pub fn new(avoid_breaking_exported_api: bool) -> Self {
|
||||
pub fn new(avoid_breaking_exported_api: bool, maximum_size: u64) -> Self {
|
||||
Self {
|
||||
avoid_breaking_exported_api,
|
||||
maximum_size,
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,8 +76,10 @@ impl UnnecessaryBoxReturns {
|
||||
|
||||
let boxed_ty = return_ty.boxed_ty();
|
||||
|
||||
// it's sometimes useful to return Box<T> if T is unsized, so don't lint those
|
||||
if boxed_ty.is_sized(cx.tcx, cx.param_env) {
|
||||
// It's sometimes useful to return Box<T> if T is unsized, so don't lint those.
|
||||
// Also, don't lint if we know that T is very large, in which case returning
|
||||
// a Box<T> may be beneficial.
|
||||
if boxed_ty.is_sized(cx.tcx, cx.param_env) && approx_ty_size(cx, boxed_ty) <= self.maximum_size {
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
UNNECESSARY_BOX_RETURNS,
|
||||
|
@ -463,6 +463,10 @@ define_Conf! {
|
||||
///
|
||||
/// The maximum byte size a `Future` can have, before it triggers the `clippy::large_futures` lint
|
||||
(future_size_threshold: u64 = 16 * 1024),
|
||||
/// Lint: UNNECESSARY_BOX_RETURNS.
|
||||
///
|
||||
/// The byte size a `T` in `Box<T>` can have, below which it triggers the `clippy::unnecessary_box` lint
|
||||
(unnecessary_box_size: u64 = 128),
|
||||
}
|
||||
|
||||
/// Search for the configuration file.
|
||||
|
@ -20,7 +20,7 @@ use std::str;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for usages of def paths when a diagnostic item or a `LangItem` could be used.
|
||||
/// Checks for usage of def paths when a diagnostic item or a `LangItem` could be used.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// The path for an item is subject to change and is less efficient to look up than a
|
||||
|
@ -104,7 +104,7 @@ declare_clippy_lint! {
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for use of `Debug` formatting. The purpose of this
|
||||
/// Checks for usage of `Debug` formatting. The purpose of this
|
||||
/// lint is to catch debugging remnants.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
|
@ -10,7 +10,7 @@ proc-macro = true
|
||||
[dependencies]
|
||||
itertools = "0.10.1"
|
||||
quote = "1.0.21"
|
||||
syn = "1.0.100"
|
||||
syn = "2.0"
|
||||
|
||||
[features]
|
||||
deny-warnings = []
|
||||
|
@ -6,16 +6,16 @@
|
||||
use proc_macro::TokenStream;
|
||||
use quote::{format_ident, quote};
|
||||
use syn::parse::{Parse, ParseStream};
|
||||
use syn::{parse_macro_input, Attribute, Error, Ident, Lit, LitStr, Meta, Result, Token};
|
||||
use syn::{parse_macro_input, Attribute, Error, Expr, ExprLit, Ident, Lit, LitStr, Meta, Result, Token};
|
||||
|
||||
fn parse_attr<const LEN: usize>(path: [&'static str; LEN], attr: &Attribute) -> Option<LitStr> {
|
||||
if let Meta::NameValue(name_value) = attr.parse_meta().ok()? {
|
||||
if let Meta::NameValue(name_value) = &attr.meta {
|
||||
let path_idents = name_value.path.segments.iter().map(|segment| &segment.ident);
|
||||
|
||||
if itertools::equal(path_idents, path)
|
||||
&& let Lit::Str(lit) = name_value.lit
|
||||
&& let Expr::Lit(ExprLit { lit: Lit::Str(s), .. }) = &name_value.value
|
||||
{
|
||||
return Some(lit);
|
||||
return Some(s.clone());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,6 +126,7 @@ fn base_config(test_dir: &str) -> compiletest::Config {
|
||||
let mut config = compiletest::Config {
|
||||
edition: Some("2021".into()),
|
||||
mode: TestMode::Ui,
|
||||
strict_headers: true,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
@ -424,7 +425,7 @@ fn check_rustfix_coverage() {
|
||||
.binary_search_by_key(&filename, Path::new)
|
||||
.is_ok(),
|
||||
"`{rs_file}` runs `MachineApplicable` diagnostics but is missing a `run-rustfix` annotation. \
|
||||
Please either add `// run-rustfix` at the top of the file or add the file to \
|
||||
Please either add `//@run-rustfix` at the top of the file or add the file to \
|
||||
`RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS` in `tests/compile-test.rs`.",
|
||||
);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// compile-flags: --crate-name=cargo_common_metadata
|
||||
//@compile-flags: --crate-name=cargo_common_metadata
|
||||
#![warn(clippy::cargo_common_metadata)]
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// compile-flags: --crate-name=cargo_common_metadata
|
||||
//@compile-flags: --crate-name=cargo_common_metadata
|
||||
#![warn(clippy::cargo_common_metadata)]
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// compile-flags: --crate-name=cargo_common_metadata
|
||||
//@compile-flags: --crate-name=cargo_common_metadata
|
||||
#![warn(clippy::cargo_common_metadata)]
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// compile-flags: --crate-name=cargo_common_metadata
|
||||
//@compile-flags: --crate-name=cargo_common_metadata
|
||||
#![warn(clippy::cargo_common_metadata)]
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// compile-flags: --crate-name=cargo_common_metadata
|
||||
//@compile-flags: --crate-name=cargo_common_metadata
|
||||
#![warn(clippy::cargo_common_metadata)]
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// compile-flags: --crate-name=cargo_common_metadata
|
||||
//@compile-flags: --crate-name=cargo_common_metadata
|
||||
#![warn(clippy::cargo_common_metadata)]
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// compile-flags: --crate-name=feature_name
|
||||
//@compile-flags: --crate-name=feature_name
|
||||
#![warn(clippy::redundant_feature_names)]
|
||||
#![warn(clippy::negative_feature_names)]
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// compile-flags: --crate-name=feature_name
|
||||
//@compile-flags: --crate-name=feature_name
|
||||
#![warn(clippy::redundant_feature_names)]
|
||||
#![warn(clippy::negative_feature_names)]
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// compile-flags: --remap-path-prefix {{src-base}}=/remapped
|
||||
//@compile-flags: --remap-path-prefix {{src-base}}=/remapped
|
||||
|
||||
#![warn(clippy::self_named_module_files)]
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// compile-flags: --crate-name=multiple_crate_versions
|
||||
//@compile-flags: --crate-name=multiple_crate_versions
|
||||
#![warn(clippy::multiple_crate_versions)]
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// compile-flags: --crate-name=multiple_crate_versions
|
||||
//@compile-flags: --crate-name=multiple_crate_versions
|
||||
#![warn(clippy::multiple_crate_versions)]
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// compile-flags: --crate-name=multiple_crate_versions
|
||||
//@compile-flags: --crate-name=multiple_crate_versions
|
||||
#![warn(clippy::multiple_crate_versions)]
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// compile-flags: --crate-name=wildcard_dependencies
|
||||
//@compile-flags: --crate-name=wildcard_dependencies
|
||||
#![warn(clippy::wildcard_dependencies)]
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// compile-flags: --crate-name=wildcard_dependencies
|
||||
//@compile-flags: --crate-name=wildcard_dependencies
|
||||
#![warn(clippy::wildcard_dependencies)]
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// run-rustfix
|
||||
//@run-rustfix
|
||||
#![deny(clippy::internal)]
|
||||
#![allow(clippy::missing_clippy_version_attribute)]
|
||||
#![feature(rustc_private)]
|
||||
|
@ -1,4 +1,4 @@
|
||||
// run-rustfix
|
||||
//@run-rustfix
|
||||
#![deny(clippy::internal)]
|
||||
#![allow(clippy::missing_clippy_version_attribute)]
|
||||
#![feature(rustc_private)]
|
||||
|
@ -1,9 +1,9 @@
|
||||
// rustc-env:RUST_BACKTRACE=0
|
||||
// normalize-stderr-test: "Clippy version: .*" -> "Clippy version: foo"
|
||||
// normalize-stderr-test: "produce_ice.rs:\d*:\d*" -> "produce_ice.rs"
|
||||
// normalize-stderr-test: "', .*clippy_lints" -> "', clippy_lints"
|
||||
// normalize-stderr-test: "'rustc'" -> "'<unnamed>'"
|
||||
// normalize-stderr-test: "(?ms)query stack during panic:\n.*end of query stack\n" -> ""
|
||||
//@rustc-env:RUST_BACKTRACE=0
|
||||
//@normalize-stderr-test: "Clippy version: .*" -> "Clippy version: foo"
|
||||
//@normalize-stderr-test: "produce_ice.rs:\d*:\d*" -> "produce_ice.rs"
|
||||
//@normalize-stderr-test: "', .*clippy_lints" -> "', clippy_lints"
|
||||
//@normalize-stderr-test: "'rustc'" -> "'<unnamed>'"
|
||||
//@normalize-stderr-test: "(?ms)query stack during panic:\n.*end of query stack\n" -> ""
|
||||
|
||||
#![deny(clippy::internal)]
|
||||
#![allow(clippy::missing_clippy_version_attribute)]
|
||||
|
@ -1,4 +1,4 @@
|
||||
// run-rustfix
|
||||
//@run-rustfix
|
||||
#![deny(clippy::internal)]
|
||||
#![allow(clippy::missing_clippy_version_attribute, clippy::let_unit_value)]
|
||||
#![feature(rustc_private)]
|
||||
|
@ -1,4 +1,4 @@
|
||||
// run-rustfix
|
||||
//@run-rustfix
|
||||
#![deny(clippy::internal)]
|
||||
#![allow(clippy::missing_clippy_version_attribute, clippy::let_unit_value)]
|
||||
#![feature(rustc_private)]
|
||||
|
@ -1,4 +1,4 @@
|
||||
// run-rustfix
|
||||
//@run-rustfix
|
||||
|
||||
#![deny(clippy::internal)]
|
||||
#![allow(clippy::missing_clippy_version_attribute)]
|
||||
|
@ -1,4 +1,4 @@
|
||||
// run-rustfix
|
||||
//@run-rustfix
|
||||
|
||||
#![deny(clippy::internal)]
|
||||
#![allow(clippy::missing_clippy_version_attribute)]
|
||||
|
@ -1,4 +1,4 @@
|
||||
// run-rustfix
|
||||
//@run-rustfix
|
||||
|
||||
#![deny(clippy::internal)]
|
||||
#![allow(clippy::missing_clippy_version_attribute)]
|
||||
|
@ -1,4 +1,4 @@
|
||||
// run-rustfix
|
||||
//@run-rustfix
|
||||
|
||||
#![deny(clippy::internal)]
|
||||
#![allow(clippy::missing_clippy_version_attribute)]
|
||||
|
@ -1,5 +1,5 @@
|
||||
// run-rustfix
|
||||
// aux-build:paths.rs
|
||||
//@run-rustfix
|
||||
//@aux-build:paths.rs
|
||||
#![deny(clippy::internal)]
|
||||
#![feature(rustc_private)]
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// run-rustfix
|
||||
// aux-build:paths.rs
|
||||
//@run-rustfix
|
||||
//@aux-build:paths.rs
|
||||
#![deny(clippy::internal)]
|
||||
#![feature(rustc_private)]
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// run-rustfix
|
||||
//@run-rustfix
|
||||
#![feature(rustc_private)]
|
||||
#![deny(clippy::internal)]
|
||||
#![allow(
|
||||
|
@ -1,4 +1,4 @@
|
||||
// run-rustfix
|
||||
//@run-rustfix
|
||||
#![feature(rustc_private)]
|
||||
#![deny(clippy::internal)]
|
||||
#![allow(
|
||||
|
@ -1,4 +1,4 @@
|
||||
// run-rustfix
|
||||
//@run-rustfix
|
||||
#![warn(clippy::uninlined_format_args)]
|
||||
|
||||
fn main() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
// run-rustfix
|
||||
//@run-rustfix
|
||||
#![warn(clippy::uninlined_format_args)]
|
||||
|
||||
fn main() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
// compile-flags: --test
|
||||
//@compile-flags: --test
|
||||
#![warn(clippy::dbg_macro)]
|
||||
|
||||
fn foo(n: u32) -> u32 {
|
||||
|
@ -1,4 +1,4 @@
|
||||
// aux-build:macros.rs
|
||||
//@aux-build:macros.rs
|
||||
|
||||
#![allow(unused)]
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// compile-flags: --test
|
||||
//@compile-flags: --test
|
||||
#![warn(clippy::expect_used)]
|
||||
|
||||
fn expect_option() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
// compile-flags: --crate-name mut_key
|
||||
//@compile-flags: --crate-name mut_key
|
||||
|
||||
#![warn(clippy::mutable_key_type)]
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// compile-flags: --emit=link
|
||||
// no-prefer-dynamic
|
||||
//@compile-flags: --emit=link
|
||||
//@no-prefer-dynamic
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// aux-build:proc_macro_derive.rs
|
||||
// run-rustfix
|
||||
//@aux-build:proc_macro_derive.rs
|
||||
//@run-rustfix
|
||||
|
||||
#![warn(clippy::nonstandard_macro_braces)]
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// aux-build:proc_macro_derive.rs
|
||||
// run-rustfix
|
||||
//@aux-build:proc_macro_derive.rs
|
||||
//@run-rustfix
|
||||
|
||||
#![warn(clippy::nonstandard_macro_braces)]
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// compile-flags: --test
|
||||
//@compile-flags: --test
|
||||
#![warn(clippy::print_stdout)]
|
||||
#![warn(clippy::print_stderr)]
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// compile-flags: --crate-name conf_disallowed_methods
|
||||
//@compile-flags: --crate-name conf_disallowed_methods
|
||||
|
||||
#![warn(clippy::disallowed_methods)]
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// normalize-stderr-test "\(\d+ byte\)" -> "(N byte)"
|
||||
// normalize-stderr-test "\(limit: \d+ byte\)" -> "(limit: N byte)"
|
||||
//@normalize-stderr-test: "\(\d+ byte\)" -> "(N byte)"
|
||||
//@normalize-stderr-test: "\(limit: \d+ byte\)" -> "(limit: N byte)"
|
||||
|
||||
#![deny(clippy::trivially_copy_pass_by_ref)]
|
||||
|
||||
|
@ -1 +1,3 @@
|
||||
//@error-pattern: unknown field `foobar`, expected one of
|
||||
|
||||
fn main() {}
|
||||
|
@ -46,6 +46,7 @@ error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown fie
|
||||
too-many-lines-threshold
|
||||
trivial-copy-size-limit
|
||||
type-complexity-threshold
|
||||
unnecessary-box-size
|
||||
unreadable-literal-lint-fractions
|
||||
upper-case-acronyms-aggressive
|
||||
vec-box-size-threshold
|
||||
|
@ -1,4 +1,4 @@
|
||||
// compile-flags: --test
|
||||
//@compile-flags: --test
|
||||
|
||||
#![allow(unused_mut, clippy::get_first, clippy::from_iter_instead_of_collect)]
|
||||
#![warn(clippy::unwrap_used)]
|
||||
|
@ -1,4 +1,4 @@
|
||||
// run-rustfix
|
||||
//@run-rustfix
|
||||
#![allow(unused)]
|
||||
#![warn(clippy::allow_attributes)]
|
||||
#![feature(lint_reasons)]
|
||||
|
@ -1,4 +1,4 @@
|
||||
// run-rustfix
|
||||
//@run-rustfix
|
||||
#![allow(unused)]
|
||||
#![warn(clippy::allow_attributes)]
|
||||
#![feature(lint_reasons)]
|
||||
|
@ -1,6 +1,6 @@
|
||||
// run-rustfix
|
||||
// edition:2018
|
||||
// aux-build:proc_macros.rs
|
||||
//@run-rustfix
|
||||
//@edition:2018
|
||||
//@aux-build:proc_macros.rs
|
||||
|
||||
#![feature(exclusive_range_pattern)]
|
||||
#![feature(stmt_expr_attributes)]
|
||||
|
@ -1,6 +1,6 @@
|
||||
// run-rustfix
|
||||
// edition:2018
|
||||
// aux-build:proc_macros.rs
|
||||
//@run-rustfix
|
||||
//@edition:2018
|
||||
//@aux-build:proc_macros.rs
|
||||
|
||||
#![feature(exclusive_range_pattern)]
|
||||
#![feature(stmt_expr_attributes)]
|
||||
|
@ -1,3 +1,5 @@
|
||||
//@aux-build:proc_macro_derive.rs
|
||||
|
||||
#![allow(
|
||||
clippy::assign_op_pattern,
|
||||
clippy::erasing_op,
|
||||
@ -11,6 +13,8 @@
|
||||
#![feature(const_mut_refs, inline_const, saturating_int_impl)]
|
||||
#![warn(clippy::arithmetic_side_effects)]
|
||||
|
||||
extern crate proc_macro_derive;
|
||||
|
||||
use core::num::{Saturating, Wrapping};
|
||||
|
||||
const ONE: i32 = 1;
|
||||
@ -19,6 +23,9 @@ const ZERO: i32 = 0;
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Custom;
|
||||
|
||||
#[derive(proc_macro_derive::ShadowDerive)]
|
||||
pub struct Nothing;
|
||||
|
||||
macro_rules! impl_arith {
|
||||
( $( $_trait:ident, $lhs:ty, $rhs:ty, $method:ident; )* ) => {
|
||||
$(
|
||||
@ -269,6 +276,17 @@ pub fn non_overflowing_ops_or_ops_already_handled_by_the_compiler_should_not_tri
|
||||
_n = &1 * _n;
|
||||
_n = 23 + 85;
|
||||
|
||||
// Method
|
||||
_n.saturating_div(1);
|
||||
_n.wrapping_div(1);
|
||||
_n.wrapping_rem(1);
|
||||
_n.wrapping_rem_euclid(1);
|
||||
|
||||
_n.saturating_div(1);
|
||||
_n.checked_div(1);
|
||||
_n.checked_rem(1);
|
||||
_n.checked_rem_euclid(1);
|
||||
|
||||
// Unary
|
||||
_n = -2147483647;
|
||||
_n = -i32::MAX;
|
||||
@ -376,6 +394,17 @@ pub fn unknown_ops_or_runtime_ops_that_can_overflow() {
|
||||
_custom = Custom << _custom;
|
||||
_custom = &Custom << _custom;
|
||||
|
||||
// Method
|
||||
_n.saturating_div(0);
|
||||
_n.wrapping_div(0);
|
||||
_n.wrapping_rem(0);
|
||||
_n.wrapping_rem_euclid(0);
|
||||
|
||||
_n.saturating_div(_n);
|
||||
_n.wrapping_div(_n);
|
||||
_n.wrapping_rem(_n);
|
||||
_n.wrapping_rem_euclid(_n);
|
||||
|
||||
// Unary
|
||||
_n = -_n;
|
||||
_n = -&_n;
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:286:5
|
||||
--> $DIR/arithmetic_side_effects.rs:304:5
|
||||
|
|
||||
LL | _n += 1;
|
||||
| ^^^^^^^
|
||||
@ -7,652 +7,700 @@ LL | _n += 1;
|
||||
= note: `-D clippy::arithmetic-side-effects` implied by `-D warnings`
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:287:5
|
||||
--> $DIR/arithmetic_side_effects.rs:305:5
|
||||
|
|
||||
LL | _n += &1;
|
||||
| ^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:288:5
|
||||
--> $DIR/arithmetic_side_effects.rs:306:5
|
||||
|
|
||||
LL | _n -= 1;
|
||||
| ^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:289:5
|
||||
--> $DIR/arithmetic_side_effects.rs:307:5
|
||||
|
|
||||
LL | _n -= &1;
|
||||
| ^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:290:5
|
||||
--> $DIR/arithmetic_side_effects.rs:308:5
|
||||
|
|
||||
LL | _n /= 0;
|
||||
| ^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:291:5
|
||||
--> $DIR/arithmetic_side_effects.rs:309:5
|
||||
|
|
||||
LL | _n /= &0;
|
||||
| ^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:292:5
|
||||
--> $DIR/arithmetic_side_effects.rs:310:5
|
||||
|
|
||||
LL | _n %= 0;
|
||||
| ^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:293:5
|
||||
--> $DIR/arithmetic_side_effects.rs:311:5
|
||||
|
|
||||
LL | _n %= &0;
|
||||
| ^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:294:5
|
||||
--> $DIR/arithmetic_side_effects.rs:312:5
|
||||
|
|
||||
LL | _n *= 2;
|
||||
| ^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:295:5
|
||||
--> $DIR/arithmetic_side_effects.rs:313:5
|
||||
|
|
||||
LL | _n *= &2;
|
||||
| ^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:296:5
|
||||
--> $DIR/arithmetic_side_effects.rs:314:5
|
||||
|
|
||||
LL | _n += -1;
|
||||
| ^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:297:5
|
||||
--> $DIR/arithmetic_side_effects.rs:315:5
|
||||
|
|
||||
LL | _n += &-1;
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:298:5
|
||||
--> $DIR/arithmetic_side_effects.rs:316:5
|
||||
|
|
||||
LL | _n -= -1;
|
||||
| ^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:299:5
|
||||
--> $DIR/arithmetic_side_effects.rs:317:5
|
||||
|
|
||||
LL | _n -= &-1;
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:300:5
|
||||
--> $DIR/arithmetic_side_effects.rs:318:5
|
||||
|
|
||||
LL | _n /= -0;
|
||||
| ^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:301:5
|
||||
--> $DIR/arithmetic_side_effects.rs:319:5
|
||||
|
|
||||
LL | _n /= &-0;
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:302:5
|
||||
--> $DIR/arithmetic_side_effects.rs:320:5
|
||||
|
|
||||
LL | _n %= -0;
|
||||
| ^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:303:5
|
||||
--> $DIR/arithmetic_side_effects.rs:321:5
|
||||
|
|
||||
LL | _n %= &-0;
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:304:5
|
||||
--> $DIR/arithmetic_side_effects.rs:322:5
|
||||
|
|
||||
LL | _n *= -2;
|
||||
| ^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:305:5
|
||||
--> $DIR/arithmetic_side_effects.rs:323:5
|
||||
|
|
||||
LL | _n *= &-2;
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:306:5
|
||||
--> $DIR/arithmetic_side_effects.rs:324:5
|
||||
|
|
||||
LL | _custom += Custom;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:307:5
|
||||
--> $DIR/arithmetic_side_effects.rs:325:5
|
||||
|
|
||||
LL | _custom += &Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:308:5
|
||||
--> $DIR/arithmetic_side_effects.rs:326:5
|
||||
|
|
||||
LL | _custom -= Custom;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:309:5
|
||||
--> $DIR/arithmetic_side_effects.rs:327:5
|
||||
|
|
||||
LL | _custom -= &Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:310:5
|
||||
--> $DIR/arithmetic_side_effects.rs:328:5
|
||||
|
|
||||
LL | _custom /= Custom;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:311:5
|
||||
--> $DIR/arithmetic_side_effects.rs:329:5
|
||||
|
|
||||
LL | _custom /= &Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:312:5
|
||||
--> $DIR/arithmetic_side_effects.rs:330:5
|
||||
|
|
||||
LL | _custom %= Custom;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:313:5
|
||||
--> $DIR/arithmetic_side_effects.rs:331:5
|
||||
|
|
||||
LL | _custom %= &Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:314:5
|
||||
--> $DIR/arithmetic_side_effects.rs:332:5
|
||||
|
|
||||
LL | _custom *= Custom;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:315:5
|
||||
--> $DIR/arithmetic_side_effects.rs:333:5
|
||||
|
|
||||
LL | _custom *= &Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:316:5
|
||||
--> $DIR/arithmetic_side_effects.rs:334:5
|
||||
|
|
||||
LL | _custom >>= Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:317:5
|
||||
--> $DIR/arithmetic_side_effects.rs:335:5
|
||||
|
|
||||
LL | _custom >>= &Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:318:5
|
||||
--> $DIR/arithmetic_side_effects.rs:336:5
|
||||
|
|
||||
LL | _custom <<= Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:319:5
|
||||
--> $DIR/arithmetic_side_effects.rs:337:5
|
||||
|
|
||||
LL | _custom <<= &Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:320:5
|
||||
--> $DIR/arithmetic_side_effects.rs:338:5
|
||||
|
|
||||
LL | _custom += -Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:321:5
|
||||
--> $DIR/arithmetic_side_effects.rs:339:5
|
||||
|
|
||||
LL | _custom += &-Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:322:5
|
||||
--> $DIR/arithmetic_side_effects.rs:340:5
|
||||
|
|
||||
LL | _custom -= -Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:323:5
|
||||
--> $DIR/arithmetic_side_effects.rs:341:5
|
||||
|
|
||||
LL | _custom -= &-Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:324:5
|
||||
--> $DIR/arithmetic_side_effects.rs:342:5
|
||||
|
|
||||
LL | _custom /= -Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:325:5
|
||||
--> $DIR/arithmetic_side_effects.rs:343:5
|
||||
|
|
||||
LL | _custom /= &-Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:326:5
|
||||
--> $DIR/arithmetic_side_effects.rs:344:5
|
||||
|
|
||||
LL | _custom %= -Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:327:5
|
||||
--> $DIR/arithmetic_side_effects.rs:345:5
|
||||
|
|
||||
LL | _custom %= &-Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:328:5
|
||||
--> $DIR/arithmetic_side_effects.rs:346:5
|
||||
|
|
||||
LL | _custom *= -Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:329:5
|
||||
--> $DIR/arithmetic_side_effects.rs:347:5
|
||||
|
|
||||
LL | _custom *= &-Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:330:5
|
||||
--> $DIR/arithmetic_side_effects.rs:348:5
|
||||
|
|
||||
LL | _custom >>= -Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:331:5
|
||||
--> $DIR/arithmetic_side_effects.rs:349:5
|
||||
|
|
||||
LL | _custom >>= &-Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:332:5
|
||||
--> $DIR/arithmetic_side_effects.rs:350:5
|
||||
|
|
||||
LL | _custom <<= -Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:333:5
|
||||
--> $DIR/arithmetic_side_effects.rs:351:5
|
||||
|
|
||||
LL | _custom <<= &-Custom;
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:336:10
|
||||
--> $DIR/arithmetic_side_effects.rs:354:10
|
||||
|
|
||||
LL | _n = _n + 1;
|
||||
| ^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:337:10
|
||||
--> $DIR/arithmetic_side_effects.rs:355:10
|
||||
|
|
||||
LL | _n = _n + &1;
|
||||
| ^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:338:10
|
||||
--> $DIR/arithmetic_side_effects.rs:356:10
|
||||
|
|
||||
LL | _n = 1 + _n;
|
||||
| ^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:339:10
|
||||
--> $DIR/arithmetic_side_effects.rs:357:10
|
||||
|
|
||||
LL | _n = &1 + _n;
|
||||
| ^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:340:10
|
||||
--> $DIR/arithmetic_side_effects.rs:358:10
|
||||
|
|
||||
LL | _n = _n - 1;
|
||||
| ^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:341:10
|
||||
--> $DIR/arithmetic_side_effects.rs:359:10
|
||||
|
|
||||
LL | _n = _n - &1;
|
||||
| ^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:342:10
|
||||
--> $DIR/arithmetic_side_effects.rs:360:10
|
||||
|
|
||||
LL | _n = 1 - _n;
|
||||
| ^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:343:10
|
||||
--> $DIR/arithmetic_side_effects.rs:361:10
|
||||
|
|
||||
LL | _n = &1 - _n;
|
||||
| ^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:344:10
|
||||
--> $DIR/arithmetic_side_effects.rs:362:10
|
||||
|
|
||||
LL | _n = _n / 0;
|
||||
| ^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:345:10
|
||||
--> $DIR/arithmetic_side_effects.rs:363:10
|
||||
|
|
||||
LL | _n = _n / &0;
|
||||
| ^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:346:10
|
||||
--> $DIR/arithmetic_side_effects.rs:364:10
|
||||
|
|
||||
LL | _n = _n % 0;
|
||||
| ^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:347:10
|
||||
--> $DIR/arithmetic_side_effects.rs:365:10
|
||||
|
|
||||
LL | _n = _n % &0;
|
||||
| ^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:348:10
|
||||
--> $DIR/arithmetic_side_effects.rs:366:10
|
||||
|
|
||||
LL | _n = _n * 2;
|
||||
| ^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:349:10
|
||||
--> $DIR/arithmetic_side_effects.rs:367:10
|
||||
|
|
||||
LL | _n = _n * &2;
|
||||
| ^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:350:10
|
||||
--> $DIR/arithmetic_side_effects.rs:368:10
|
||||
|
|
||||
LL | _n = 2 * _n;
|
||||
| ^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:351:10
|
||||
--> $DIR/arithmetic_side_effects.rs:369:10
|
||||
|
|
||||
LL | _n = &2 * _n;
|
||||
| ^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:352:10
|
||||
--> $DIR/arithmetic_side_effects.rs:370:10
|
||||
|
|
||||
LL | _n = 23 + &85;
|
||||
| ^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:353:10
|
||||
--> $DIR/arithmetic_side_effects.rs:371:10
|
||||
|
|
||||
LL | _n = &23 + 85;
|
||||
| ^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:354:10
|
||||
--> $DIR/arithmetic_side_effects.rs:372:10
|
||||
|
|
||||
LL | _n = &23 + &85;
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:355:15
|
||||
--> $DIR/arithmetic_side_effects.rs:373:15
|
||||
|
|
||||
LL | _custom = _custom + _custom;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:356:15
|
||||
--> $DIR/arithmetic_side_effects.rs:374:15
|
||||
|
|
||||
LL | _custom = _custom + &_custom;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:357:15
|
||||
--> $DIR/arithmetic_side_effects.rs:375:15
|
||||
|
|
||||
LL | _custom = Custom + _custom;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:358:15
|
||||
--> $DIR/arithmetic_side_effects.rs:376:15
|
||||
|
|
||||
LL | _custom = &Custom + _custom;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:359:15
|
||||
--> $DIR/arithmetic_side_effects.rs:377:15
|
||||
|
|
||||
LL | _custom = _custom - Custom;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:360:15
|
||||
--> $DIR/arithmetic_side_effects.rs:378:15
|
||||
|
|
||||
LL | _custom = _custom - &Custom;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:361:15
|
||||
--> $DIR/arithmetic_side_effects.rs:379:15
|
||||
|
|
||||
LL | _custom = Custom - _custom;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:362:15
|
||||
--> $DIR/arithmetic_side_effects.rs:380:15
|
||||
|
|
||||
LL | _custom = &Custom - _custom;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:363:15
|
||||
--> $DIR/arithmetic_side_effects.rs:381:15
|
||||
|
|
||||
LL | _custom = _custom / Custom;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:364:15
|
||||
--> $DIR/arithmetic_side_effects.rs:382:15
|
||||
|
|
||||
LL | _custom = _custom / &Custom;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:365:15
|
||||
--> $DIR/arithmetic_side_effects.rs:383:15
|
||||
|
|
||||
LL | _custom = _custom % Custom;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:366:15
|
||||
--> $DIR/arithmetic_side_effects.rs:384:15
|
||||
|
|
||||
LL | _custom = _custom % &Custom;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:367:15
|
||||
--> $DIR/arithmetic_side_effects.rs:385:15
|
||||
|
|
||||
LL | _custom = _custom * Custom;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:368:15
|
||||
--> $DIR/arithmetic_side_effects.rs:386:15
|
||||
|
|
||||
LL | _custom = _custom * &Custom;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:369:15
|
||||
--> $DIR/arithmetic_side_effects.rs:387:15
|
||||
|
|
||||
LL | _custom = Custom * _custom;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:370:15
|
||||
--> $DIR/arithmetic_side_effects.rs:388:15
|
||||
|
|
||||
LL | _custom = &Custom * _custom;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:371:15
|
||||
--> $DIR/arithmetic_side_effects.rs:389:15
|
||||
|
|
||||
LL | _custom = Custom + &Custom;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:372:15
|
||||
--> $DIR/arithmetic_side_effects.rs:390:15
|
||||
|
|
||||
LL | _custom = &Custom + Custom;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:373:15
|
||||
--> $DIR/arithmetic_side_effects.rs:391:15
|
||||
|
|
||||
LL | _custom = &Custom + &Custom;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:374:15
|
||||
--> $DIR/arithmetic_side_effects.rs:392:15
|
||||
|
|
||||
LL | _custom = _custom >> _custom;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:375:15
|
||||
--> $DIR/arithmetic_side_effects.rs:393:15
|
||||
|
|
||||
LL | _custom = _custom >> &_custom;
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:376:15
|
||||
--> $DIR/arithmetic_side_effects.rs:394:15
|
||||
|
|
||||
LL | _custom = Custom << _custom;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:377:15
|
||||
--> $DIR/arithmetic_side_effects.rs:395:15
|
||||
|
|
||||
LL | _custom = &Custom << _custom;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:380:10
|
||||
--> $DIR/arithmetic_side_effects.rs:398:23
|
||||
|
|
||||
LL | _n.saturating_div(0);
|
||||
| ^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:399:21
|
||||
|
|
||||
LL | _n.wrapping_div(0);
|
||||
| ^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:400:21
|
||||
|
|
||||
LL | _n.wrapping_rem(0);
|
||||
| ^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:401:28
|
||||
|
|
||||
LL | _n.wrapping_rem_euclid(0);
|
||||
| ^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:403:23
|
||||
|
|
||||
LL | _n.saturating_div(_n);
|
||||
| ^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:404:21
|
||||
|
|
||||
LL | _n.wrapping_div(_n);
|
||||
| ^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:405:21
|
||||
|
|
||||
LL | _n.wrapping_rem(_n);
|
||||
| ^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:406:28
|
||||
|
|
||||
LL | _n.wrapping_rem_euclid(_n);
|
||||
| ^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:409:10
|
||||
|
|
||||
LL | _n = -_n;
|
||||
| ^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:381:10
|
||||
--> $DIR/arithmetic_side_effects.rs:410:10
|
||||
|
|
||||
LL | _n = -&_n;
|
||||
| ^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:382:15
|
||||
--> $DIR/arithmetic_side_effects.rs:411:15
|
||||
|
|
||||
LL | _custom = -_custom;
|
||||
| ^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:383:15
|
||||
--> $DIR/arithmetic_side_effects.rs:412:15
|
||||
|
|
||||
LL | _custom = -&_custom;
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:392:5
|
||||
--> $DIR/arithmetic_side_effects.rs:421:5
|
||||
|
|
||||
LL | 1 + i;
|
||||
| ^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:393:5
|
||||
--> $DIR/arithmetic_side_effects.rs:422:5
|
||||
|
|
||||
LL | i * 2;
|
||||
| ^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:394:5
|
||||
--> $DIR/arithmetic_side_effects.rs:423:5
|
||||
|
|
||||
LL | 1 % i / 2;
|
||||
| ^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:395:5
|
||||
--> $DIR/arithmetic_side_effects.rs:424:5
|
||||
|
|
||||
LL | i - 2 + 2 - i;
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:396:5
|
||||
--> $DIR/arithmetic_side_effects.rs:425:5
|
||||
|
|
||||
LL | -i;
|
||||
| ^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:407:5
|
||||
--> $DIR/arithmetic_side_effects.rs:436:5
|
||||
|
|
||||
LL | i += 1;
|
||||
| ^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:408:5
|
||||
--> $DIR/arithmetic_side_effects.rs:437:5
|
||||
|
|
||||
LL | i -= 1;
|
||||
| ^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:409:5
|
||||
--> $DIR/arithmetic_side_effects.rs:438:5
|
||||
|
|
||||
LL | i *= 2;
|
||||
| ^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:411:5
|
||||
--> $DIR/arithmetic_side_effects.rs:440:5
|
||||
|
|
||||
LL | i /= 0;
|
||||
| ^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:413:5
|
||||
--> $DIR/arithmetic_side_effects.rs:442:5
|
||||
|
|
||||
LL | i /= var1;
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:414:5
|
||||
--> $DIR/arithmetic_side_effects.rs:443:5
|
||||
|
|
||||
LL | i /= var2;
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:416:5
|
||||
--> $DIR/arithmetic_side_effects.rs:445:5
|
||||
|
|
||||
LL | i %= 0;
|
||||
| ^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:418:5
|
||||
--> $DIR/arithmetic_side_effects.rs:447:5
|
||||
|
|
||||
LL | i %= var1;
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:419:5
|
||||
--> $DIR/arithmetic_side_effects.rs:448:5
|
||||
|
|
||||
LL | i %= var2;
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: arithmetic operation that can potentially result in unexpected side-effects
|
||||
--> $DIR/arithmetic_side_effects.rs:429:5
|
||||
--> $DIR/arithmetic_side_effects.rs:458:5
|
||||
|
|
||||
LL | 10 / a
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 109 previous errors
|
||||
error: aborting due to 117 previous errors
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// aux-build:proc_macros.rs
|
||||
//@aux-build:proc_macros.rs
|
||||
|
||||
#![warn(clippy::as_conversions)]
|
||||
#![allow(clippy::borrow_as_ptr)]
|
||||
|
@ -1,4 +1,4 @@
|
||||
// run-rustfix
|
||||
//@run-rustfix
|
||||
|
||||
#![warn(clippy::as_underscore)]
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// run-rustfix
|
||||
//@run-rustfix
|
||||
|
||||
#![warn(clippy::as_underscore)]
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// only-x86_64
|
||||
// ignore-aarch64
|
||||
//@only-x86_64
|
||||
//@ignore-aarch64
|
||||
|
||||
#[warn(clippy::inline_asm_x86_intel_syntax)]
|
||||
mod warn_intel {
|
||||
|
@ -1,4 +1,4 @@
|
||||
// run-rustfix
|
||||
//@run-rustfix
|
||||
#![warn(clippy::assertions_on_result_states)]
|
||||
|
||||
use std::result::Result;
|
||||
|
@ -1,4 +1,4 @@
|
||||
// run-rustfix
|
||||
//@run-rustfix
|
||||
#![warn(clippy::assertions_on_result_states)]
|
||||
|
||||
use std::result::Result;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user