Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup

This commit is contained in:
Philipp Krones 2023-04-23 13:03:09 +02:00
commit 4beb0a4bdf
No known key found for this signature in database
GPG key ID: 1CA0DF2AF59D68A5
783 changed files with 2368 additions and 1464 deletions

View file

@ -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

View file

@ -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"] }

View file

@ -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)

View file

@ -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

View file

@ -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.

View 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

View 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

View file

@ -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

View file

@ -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)

View file

@ -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();

View file

@ -6,7 +6,7 @@
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`

View file

@ -506,7 +506,7 @@
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 @@
///
/// ### 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"]

View file

@ -9,7 +9,7 @@
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

View file

@ -215,6 +215,7 @@
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,

View file

@ -19,7 +19,7 @@
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?

View file

@ -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",
);

View file

@ -51,7 +51,7 @@
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?

View file

@ -10,7 +10,7 @@
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?

View file

@ -348,7 +348,7 @@
/// // [...]
/// }
/// ```
#[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"

View 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);
}
}
}
}
}
}
}

View file

@ -168,25 +168,27 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
}
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
_ => (),
}
}

View file

@ -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 @@ fn check_local(&mut self, cx: &LateContext<'_>, local: &Local<'_>) {
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,

View file

@ -158,6 +158,7 @@
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`
}

View file

@ -10,7 +10,7 @@
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?

View file

@ -13,7 +13,7 @@
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?

View file

@ -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 @@
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()

View file

@ -843,7 +843,7 @@
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! {
/// ### 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! {
/// ### 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.

View file

@ -121,7 +121,7 @@
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! {
/// ### 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! {
/// ### 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! {
/// ### 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! {
/// ### 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! {
/// ### 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! {
/// ### 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! {
/// ### 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! {
/// ### 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! {
/// ### 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! {
/// ### 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! {
/// ### 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! {
/// ### 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! {
/// ### 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! {
/// ### 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! {
/// ### 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 @@
/// ```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"

View file

@ -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;

View file

@ -59,7 +59,7 @@
/// 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"

View file

@ -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 @@
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! {
/// ### 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?

View file

@ -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.

View file

@ -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,
);
}
},
);
}

View file

@ -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_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 @@
["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 @@ fn manage_bin_ops<'tcx>(
}
}
/// 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 @@ fn manage_unary_ops<'tcx>(
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 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &hir::Expr<'tcx>) {
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);
},

View file

@ -685,7 +685,7 @@
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?

View file

@ -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 @@ pub fn check_binary<'tcx>(
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 @@ pub fn check_negate<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Ex
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() {

View file

@ -24,7 +24,7 @@
/// ```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"

View file

@ -17,7 +17,7 @@
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 @@
/// 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"

View file

@ -22,7 +22,7 @@
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! {
/// ### 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! {
/// ### 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! {
/// ### 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! {
/// ### 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>>`,

View file

@ -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 @@
///
/// 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 @@
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 @@ fn check_fn_item(&mut self, cx: &LateContext<'_>, decl: &FnDecl<'_>, def_id: Loc
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,

View file

@ -463,6 +463,10 @@ pub(crate) fn get_configuration_metadata() -> Vec<ClippyConfiguration> {
///
/// 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.

View file

@ -20,7 +20,7 @@
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

View file

@ -104,7 +104,7 @@
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?

View file

@ -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 = []

View file

@ -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());
}
}

View file

@ -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`.",
);
}

View file

@ -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() {}

View file

@ -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() {}

View file

@ -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() {}

View file

@ -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() {}

View file

@ -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() {}

View file

@ -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() {}

View file

@ -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)]

View file

@ -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)]

View file

@ -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)]

View file

@ -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() {}

View file

@ -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() {}

View file

@ -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() {}

View file

@ -1,4 +1,4 @@
// compile-flags: --crate-name=wildcard_dependencies
//@compile-flags: --crate-name=wildcard_dependencies
#![warn(clippy::wildcard_dependencies)]
fn main() {}

View file

@ -1,4 +1,4 @@
// compile-flags: --crate-name=wildcard_dependencies
//@compile-flags: --crate-name=wildcard_dependencies
#![warn(clippy::wildcard_dependencies)]
fn main() {}

View file

@ -1,4 +1,4 @@
// run-rustfix
//@run-rustfix
#![deny(clippy::internal)]
#![allow(clippy::missing_clippy_version_attribute)]
#![feature(rustc_private)]

View file

@ -1,4 +1,4 @@
// run-rustfix
//@run-rustfix
#![deny(clippy::internal)]
#![allow(clippy::missing_clippy_version_attribute)]
#![feature(rustc_private)]

View file

@ -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)]

View file

@ -1,4 +1,4 @@
// run-rustfix
//@run-rustfix
#![deny(clippy::internal)]
#![allow(clippy::missing_clippy_version_attribute, clippy::let_unit_value)]
#![feature(rustc_private)]

View file

@ -1,4 +1,4 @@
// run-rustfix
//@run-rustfix
#![deny(clippy::internal)]
#![allow(clippy::missing_clippy_version_attribute, clippy::let_unit_value)]
#![feature(rustc_private)]

View file

@ -1,4 +1,4 @@
// run-rustfix
//@run-rustfix
#![deny(clippy::internal)]
#![allow(clippy::missing_clippy_version_attribute)]

View file

@ -1,4 +1,4 @@
// run-rustfix
//@run-rustfix
#![deny(clippy::internal)]
#![allow(clippy::missing_clippy_version_attribute)]

View file

@ -1,4 +1,4 @@
// run-rustfix
//@run-rustfix
#![deny(clippy::internal)]
#![allow(clippy::missing_clippy_version_attribute)]

View file

@ -1,4 +1,4 @@
// run-rustfix
//@run-rustfix
#![deny(clippy::internal)]
#![allow(clippy::missing_clippy_version_attribute)]

View file

@ -1,5 +1,5 @@
// run-rustfix
// aux-build:paths.rs
//@run-rustfix
//@aux-build:paths.rs
#![deny(clippy::internal)]
#![feature(rustc_private)]

View file

@ -1,5 +1,5 @@
// run-rustfix
// aux-build:paths.rs
//@run-rustfix
//@aux-build:paths.rs
#![deny(clippy::internal)]
#![feature(rustc_private)]

View file

@ -1,4 +1,4 @@
// run-rustfix
//@run-rustfix
#![feature(rustc_private)]
#![deny(clippy::internal)]
#![allow(

View file

@ -1,4 +1,4 @@
// run-rustfix
//@run-rustfix
#![feature(rustc_private)]
#![deny(clippy::internal)]
#![allow(

View file

@ -1,4 +1,4 @@
// run-rustfix
//@run-rustfix
#![warn(clippy::uninlined_format_args)]
fn main() {

View file

@ -1,4 +1,4 @@
// run-rustfix
//@run-rustfix
#![warn(clippy::uninlined_format_args)]
fn main() {

View file

@ -1,4 +1,4 @@
// compile-flags: --test
//@compile-flags: --test
#![warn(clippy::dbg_macro)]
fn foo(n: u32) -> u32 {

View file

@ -1,4 +1,4 @@
// aux-build:macros.rs
//@aux-build:macros.rs
#![allow(unused)]

View file

@ -1,4 +1,4 @@
// compile-flags: --test
//@compile-flags: --test
#![warn(clippy::expect_used)]
fn expect_option() {

View file

@ -1,4 +1,4 @@
// compile-flags: --crate-name mut_key
//@compile-flags: --crate-name mut_key
#![warn(clippy::mutable_key_type)]

View file

@ -1,5 +1,5 @@
// compile-flags: --emit=link
// no-prefer-dynamic
//@compile-flags: --emit=link
//@no-prefer-dynamic
#![crate_type = "proc-macro"]

View file

@ -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)]

View file

@ -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)]

View file

@ -1,4 +1,4 @@
// compile-flags: --test
//@compile-flags: --test
#![warn(clippy::print_stdout)]
#![warn(clippy::print_stderr)]

View file

@ -1,4 +1,4 @@
// compile-flags: --crate-name conf_disallowed_methods
//@compile-flags: --crate-name conf_disallowed_methods
#![warn(clippy::disallowed_methods)]

View file

@ -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)]

View file

@ -1 +1,3 @@
//@error-pattern: unknown field `foobar`, expected one of
fn main() {}

View file

@ -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

View file

@ -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)]

View file

@ -1,4 +1,4 @@
// run-rustfix
//@run-rustfix
#![allow(unused)]
#![warn(clippy::allow_attributes)]
#![feature(lint_reasons)]

View file

@ -1,4 +1,4 @@
// run-rustfix
//@run-rustfix
#![allow(unused)]
#![warn(clippy::allow_attributes)]
#![feature(lint_reasons)]

View file

@ -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)]

View file

@ -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)]

View file

@ -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 @@
#[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;

View file

@ -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

View file

@ -1,4 +1,4 @@
// aux-build:proc_macros.rs
//@aux-build:proc_macros.rs
#![warn(clippy::as_conversions)]
#![allow(clippy::borrow_as_ptr)]

View file

@ -1,4 +1,4 @@
// run-rustfix
//@run-rustfix
#![warn(clippy::as_underscore)]

View file

@ -1,4 +1,4 @@
// run-rustfix
//@run-rustfix
#![warn(clippy::as_underscore)]

View file

@ -1,5 +1,5 @@
// only-x86_64
// ignore-aarch64
//@only-x86_64
//@ignore-aarch64
#[warn(clippy::inline_asm_x86_intel_syntax)]
mod warn_intel {

View file

@ -1,4 +1,4 @@
// run-rustfix
//@run-rustfix
#![warn(clippy::assertions_on_result_states)]
use std::result::Result;

View file

@ -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