[`macro_metavars_in_unsafe`]: recognize metavariables in tail expressions
Fixes#13219
`macro_metavars_in_unsafe` keeps track of the current "expansion depth" (incremented/decremented when entering/leaving a macro span) to tell if an expression from the root context is contained within a macro (see the doc comment I added for a hopefully better explanation)
Before this PR, we didn't increment said `expn_depth` for `unsafe` blocks within macros, because we already do that in `visit_stmt` anyway, so it would work fine for statements, but that's not enough for tail expressions of an unsafe block.
So we now also increment it for macro unsafe blocks.
Also updated the comment for `expn_depth` while I'm at it because "This is not necessary for correctness" isn't correct now that I think about it
------
changelog: none
Respect allow `inconsistent_struct_constructor` on the struct definition
Closes#13203
Now we check if the target type is marked with `#[allow(clippy:inconsistent_struct_constructor)]` before lining.
As a side-effect of this change, The rule in the subject no longer runs on non-local `AdtDef`s. However, as suggested by `@Jarcho` it shouldn't be a big deal since most of the time we didn't have access to this information anyway.
> You can't get lint attributes from other crates. I would probably just restrict the lint to only work with types from the current crate while you're at it. Upstream crates don't have a definition order from the point of view of the current crate (with the exception of #[repr(C)] structs).
changelog: Respect allow `inconsistent_struct_constructor` on the struct definition.
By splitting the `FnSig` within `TyKind::FnPtr` into `FnSigTys` and
`FnHeader`, which can be packed more efficiently. This reduces the size
of the hot `TyKind` type from 32 bytes to 24 bytes on 64-bit platforms.
This reduces peak memory usage by a few percent on some benchmarks. It
also reduces cache misses and page faults similarly, though this doesn't
translate to clear cycles or wall-time improvements on CI.
Don't use `LateContext` in the constant evaluator
This also changes the interface to require explicitly creating the context. `constant` could be added back in, but the others are probably not worth it.
A couple of bugs have been fixed. The wrong `TypeckResults` was used once when evaluating a constant, and the wrong `ParamEnv` was used by some callers (there wasn't a way to use the correct one).
changelog: none
Add lint for `unused_result_ok`
This PR adds a lint to capture the use of `expr.ok();` when the result is not _really_ used.
This could be interpreted as the result being checked (like it is with `unwrap()` or `expect`) but
it actually only ignores the result.
`let _ = expr;` expresses that intent better.
This was also mentionned in #8994 (although not being the main topic of that issue).
changelog: [`misleading_use_of_ok`]: Add new lint to capture `.ok();` when the result is not _really_ used.
Remove `multispan_sugg[_with_applicability]`
They're thin wrappers over the corresponding diag method so we should just use that instead
changelog: none
Fix [`redundant_slicing`] when the slice is behind a mutable reference
Fixes#12751
changelog: Fix [`redundant_slicing`] when the slice is behind a mutable reference and a immutable reference is expected.
When a suggestion part is for already present code, do not highlight it. If after that there are no highlights left, do not show the suggestion at all.
Fix clippy lint suggestion incorrectly treated as `span_help`.
Fix `redundant_closure` false positive with closures has return type contains `'static`
Fix#13073 .
Please enable "ignore white-space change" settings in github UI for easy reviewing.
HACK: The third commit contains a hack to check if a type `T: 'static` when `fn() -> U where U: 'static`.
I don't have a clean way to check for it.
changelog: [`redundant_closure`] Fix false positive with closures has return type contains `'static`
Fix false positive for `missing_backticks` in footnote references
Fixes#13183.
changelog: Fix false positive for `missing_backticks` in footnote references
Emit `if_let_mutex` in presence of other mutexes
Currently (master, not nightly nor stable) `if_let_mutex` does not emit a warning here:
```rs
let m1 = Mutex::new(10);
let m2 = Mutex::new(());
if let 100..=200 = *m1.lock().unwrap() {
m2.lock();
} else {
m1.lock();
}
```
It currently looks for the first call to `.lock()` on *any* mutex receiver inside of the if/else body, and only later (outside of the visitor) checks that the receiver matches the mutex in the scrutinee. That means that in cases like the above, it finds the `m2.lock()` expression, stops the visitor, fails the check that it's the same mutex (`m2` != `m1`) and then does not look for any other `.lock()` calls.
So, just make the receiver check also part of the visitor so that we only stop the visitor when we also find the right receiver.
The first commit has the actual changes described here. The sceond one just unnests all the `if let`s
----
changelog: none
Misc changes to `clippy_config`
Contains part of #13084
Changes include:
* Sort config list and each configs lint list.
* Add default text for the two configs that were missing it.
* Switch the lint list in the configs to an attribute.
* Make `dev fmt` sort the config list.
r? `@xFrednet`
changelog: none
`missing_trait_methods`: lint methods in definition order
Lintcheck for #13157 showed a bunch of changes for `missing_trait_methods`
This is because `values_sorted` was sorting the entries by the key's [`DefPathHash`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/def_id/struct.DefPathHash.html), this is stable for a given compiler but can change across versions
changelog: none
Fix while_let_on_iterator dropping loop label when applying fix.
Loop label was not persisted when displaying help and was therefore producing broken rust code when applying fixes.
Solution was to store the `ast::Label` when creating a `higher::WhileLet` from an expression and add the label name to the lint suggestion and diagnostics.
---
Fixes: https://github.com/rust-lang/rust-clippy/issues/13123
changelog: [`while_let_on_iterator`]: Fix issue dropping loop label when displaying help and applying fixes.
Add `BTreeSet` detection to the `set_contains_or_insert` lint
* Detect `BTreeSet::contains` + `BTreeSet::insert` usage in the same way as with the `HashSet`.
CC: `@lochetti` `@bitfield`
----
changelog: [`set_contains_or_insert`]: Handle `BTreeSet` in addition to `HashSet`
Make `std_instead_of_core` somewhat MSRV aware
For #13158, this catches some things e.g. `core::net` and the recently stable `core::error` but not things moved individually like `UnwindSafe`, as far as I can see the version for those isn't easily available
Beta nominating since ideally we'd get this change in the same version as `core::error` becomes stable
cc `@kpreid`
changelog: none
Support ?Trait bounds in supertraits and dyn Trait under a feature gate
This patch allows `maybe` polarity bounds under a feature gate. The only language change here is that corresponding hard errors are replaced by feature gates. Example:
```rust
#![feature(allow_maybe_polarity)]
...
trait Trait1 : ?Trait { ... } // ok
fn foo(_: Box<(dyn Trait2 + ?Trait)>) {} // ok
fn bar<T: ?Sized + ?Trait>(_: &T) {} // ok
```
Maybe bounds still don't do anything (except for `Sized` trait), however this patch will allow us to [experiment with default auto traits](https://github.com/rust-lang/rust/pull/120706#issuecomment-1934006762).
This is a part of the [MCP: Low level components for async drop](https://github.com/rust-lang/compiler-team/issues/727)
Avoid ref when using format!
Clean up a few minor refs in `format!` macro, as it has a performance cost. Apparently the compiler is unable to inline `format!("{}", &variable)`, and does a run-time double-reference instead (format macro already does one level referencing).
Inlining format args prevents accidental `&` misuse.
See also https://github.com/rust-lang/rust/issues/112156
changelog: none
needless_borrows_for_generic_args: Fix for &mut
This commit fixes a bug introduced in #12706, where the behavior of the lint has been changed, to avoid suggestions that introduce a move. The motivation in the commit message is quite poor (if the detection for significant drops is not sufficient because it's not transitive, the proper fix would be to make it transitive). However, #12454, the linked issue, provides a good reason for the change — if the value being borrowed is bound to a variable, then moving it will only introduce friction into future refactorings.
Thus #12706 changes the logic so that the lint triggers if the value being borrowed is Copy, or is the result of a function call, simplifying the logic to the point where analysing "is this the only use of this value" isn't necessary.
However, said PR also introduces an undocumented carveout, where referents that themselves are mutable references are treated as Copy, to catch some cases that we do want to lint against. However, that is not sound — it's possible to consume a mutable reference by moving it.
To avoid emitting false suggestions, this PR reintroduces the referent_used_exactly_once logic and runs that check for referents that are themselves mutable references.
Thinking about the code shape of &mut x, where x: &mut T, raises the point that while removing the &mut outright won't work, the extra indirection is still undesirable, and perhaps instead we should suggest reborrowing: &mut *x. That, however, is left as possible future work.
Fixes#12856
changelog: none
Implement lint against ambiguous negative literals
This PR implements a lint against ambiguous negative literals with a literal and method calls right after it.
## `ambiguous_negative_literals`
(deny-by-default)
The `ambiguous_negative_literals` lint checks for cases that are confusing between a negative literal and a negation that's not part of the literal.
### Example
```rust,compile_fail
-1i32.abs(); // equals -1, while `(-1i32).abs()` equals 1
```
### Explanation
Method calls take precedence over unary precedence. Setting the precedence explicitly makes the code clearer and avoid potential bugs.
<details>
<summary>Old proposed lint</summary>
## `ambiguous_unary_precedence`
(deny-by-default)
The `ambiguous_unary_precedence` lint checks for use the negative unary operator with a literal and method calls.
### Example
```rust
-1i32.abs(); // equals -1, while `(-1i32).abs()` equals 1
```
### Explanation
Unary operations take precedence on binary operations and method calls take precedence over unary precedence. Setting the precedence explicitly makes the code clearer and avoid potential bugs.
</details>
-----
Note: This is a strip down version of https://github.com/rust-lang/rust/pull/117161, without the binary op precedence.
Fixes https://github.com/rust-lang/rust/issues/117155
`@rustbot` labels +I-lang-nominated
cc `@scottmcm`
r? compiler
Changelog for Clippy 1.80 🌞
Roses are red,
Violets are blue,
Summer is fun,
So much sun
---
### The cat of this release is *Maunzer* submitted by `@llogiq:`
<img height=500 src="https://github.com/rust-lang/rust-clippy/assets/4200835/a1da6948-446d-4ccf-95a7-c816a8afdc3f" alt="The cats of this Clippy release" />
Cats for the next release can be nominated in the comments :D
---
changelog: none
I wish everyone reading this a beautiful and happy day =^.^=
Use ControlFlow in more places
Now, instead of manually using variables in visitors to signify that a visit is "done" and that the visitor should stop traversing. We use the trait type "Result" to signify this (in relevant places).
I'll schedule a perf run, I don't think it will be much of a difference, but every bit of performance is welcomed :)
changelog: Improve performance, less memory use in visitors
Fixes#12829
r? `@y21`
Make ast `MutVisitor` have the same method name and style as `Visitor`
It doesn't map 100% because some `MutVisitor` methods can filter or even expand to multiple items, but consistency seems nicer.
tracking issue: https://github.com/rust-lang/rust/issues/127615
Misc refactorings
Various small re-orderings to check the HIR tree or AST before doing other checks. Also includes a small bug fix for `arc_with_small_send_sync` not actually checking for `Arc::new`.
changelog: none