Modify str_to_string to be machine-applicable
Fixes https://github.com/rust-lang/rust-clippy/issues/12768
I'm not sure if there is any potential for edge cases with this - since it only ever acts on `&str` types I can't think of any, and especially since the methods do the same thing anyway.
changelog: allow `str_to_string` lint to be automatically applied
Disable `indexing_slicing` for custom Index impls
Fixes https://github.com/rust-lang/rust-clippy/issues/11525
Disables `indexing_slicing` for custom Index impls, specifically any implementations that also do not have a `get` method anywhere along the deref chain (so, for example, it still lints on Vec, which has its `get` method as part of the deref chain).
Thanks `@y21` for pointing me in the right direction with a couple of handy util functions for deref chain and inherent methods, saved a headache there!
changelog: FP: Disable `indexing_slicing` for custom Index impls
fix: let non_canonical_impls skip proc marco
Fixed#12788
Although the issue only mentions `NON_CANONICAL_CLONE_IMPL`, this fix will also affect `NON_CANONICAL_PARTIAL_ORD_IMPL` because I saw
> Because of these unforeseeable or unstable behaviors, macro expansion should often not be regarded as a part of the stable API.
on Clippy Documentation and these two lints are similar, so I think it might be good, not sure if it's right or not.
---
changelog: `NON_CANONICAL_CLONE_IMPL`, `NON_CANONICAL_PARTIAL_ORD_IMPL` will skip proc marco now
don't inhibit random field reordering on repr(packed(1))
`inhibit_struct_field_reordering_opt` being false means we exclude this type from random field shuffling. However, `packed(1)` types can still be shuffled! The logic was added in https://github.com/rust-lang/rust/pull/48528 since it's pointless to reorder fields in packed(1) types (there's no padding that could be saved) -- but that shouldn't inhibit `-Zrandomize-layout` (which did not exist at the time).
We could add an optimization elsewhere to not bother sorting the fields for `repr(packed)` types, but I don't think that's worth the effort.
This *does* change the behavior in that we may now reorder fields of `packed(1)` structs (e.g. if there are niches, we'll try to move them to the start/end, according to `NicheBias`). We were always allowed to do that but so far we didn't. Quoting the [reference](https://doc.rust-lang.org/reference/type-layout.html):
> On their own, align and packed do not provide guarantees about the order of fields in the layout of a struct or the layout of an enum variant, although they may be combined with representations (such as C) which do provide such guarantees.
[`many_single_char_names`]: Deduplicate diagnostics
Relates to #12379
Fix `many_single_char_names` lint so that it doesn't emit diagnostics when the current level of the scope doesn't contain any single character name.
```rust
let (a, b, c, d): (i32, i32, i32, i32);
match 1 {
1 => (),
e => {},
}
```
produced the exact same MANY_SINGLE_CHAR_NAMES diagnostic at each of the Arm `e => {}` and the Block `{}`.
---
changelog: [`many_single_char_names`]: Fix duplicate diagnostics
Fix `unnecessary_to_owned` interaction with macro expansion
fixes#12821
In the case of an unnecessary `.iter().cloned()`, the lint `unnecessary_to_owned` might suggest to remove the `&` from references without checking if such references are inside a macro expansion. This can lead to unexpected behavior or even broken code if the lint suggestion is applied blindly. See issue #12821 for an example.
This PR checks if such references are inside macro expansions and skips this part of the lint suggestion in these cases.
changelog: [`unnecessary_to_owned`]: Don't suggest to remove `&` inside macro expansion
[perf] Delay the construction of early lint diag structs
Attacks some of the perf regressions from https://github.com/rust-lang/rust/pull/124417#issuecomment-2123700666.
See individual commits for details. The first three commits are not strictly necessary.
However, the 2nd one (06bc4fc67145e3a7be9b5a2cf2b5968cef36e587, *Remove `LintDiagnostic::msg`*) makes the main change way nicer to implement.
It's also pretty sweet on its own if I may say so myself.
Remove `DefId` from `EarlyParamRegion`
Currently we represent usages of `Region` parameters via the `ReEarlyParam` or `ReLateParam` variants. The `ReEarlyParam` is effectively equivalent to `TyKind::Param` and `ConstKind::Param` (i.e. it stores a `Symbol` and a `u32` index) however it also stores a `DefId` for the definition of the lifetime parameter.
This was used in roughly two places:
- Borrowck diagnostics instead of threading the appropriate `body_id` down to relevant locations. Interestingly there were already some places that had to pass down a `DefId` manually.
- Some opaque type checking logic was using the `DefId` field to track captured lifetimes
I've split this PR up into a commit for generate rote changes to diagnostics code to pass around a `DefId` manually everywhere, and another commit for the opaque type related changes which likely require more careful review as they might change the semantics of lints/errors.
Instead of manually passing the `DefId` around everywhere I previously tried to bundle it in with `TypeErrCtxt` but ran into issues with some call sites of `infcx.err_ctxt` being unable to provide a `DefId`, particularly places involved with trait solving and normalization. It might be worth investigating adding some new wrapper type to pass this around everywhere but I think this might be acceptable for now.
This pr also has the effect of reducing the size of `EarlyParamRegion` from 16 bytes -> 8 bytes. I wouldn't expect this to have any direct performance improvement however, other variants of `RegionKind` over `8` bytes are all because they contain a `BoundRegionKind` which is, as far as I know, mostly there for diagnostics. If we're ever able to remove this it would shrink the `RegionKind` type from `24` bytes to `12` (and with clever bit packing we might be able to get it to `8` bytes). I am curious what the performance impact would be of removing interning of `Region`'s if we ever manage to shrink `RegionKind` that much.
Sidenote: by removing the `DefId` the `Debug` output for `Region` has gotten significantly nicer. As an example see this opaque type debug print before vs after this PR:
`Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), [DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a)_'a/#0, T, DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a)_'a/#0])`
`Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), ['a/#0, T, 'a/#0])`
r? `@compiler-errors` (I would like someone who understands the opaque type setup to atleast review the type system commit, but the rest is likely reviewable by anyone)
`significant_drop_in_scrutinee`: Trigger lint only if lifetime allows early significant drop
I want to argue that the following code snippet should not trigger `significant_drop_in_scrutinee` (https://github.com/rust-lang/rust-clippy/issues/8987). The iterator holds a reference to the locked data, so it is expected that the mutex guard must be alive until the entire loop is finished.
```rust
use std::sync::Mutex;
fn main() {
let mutex_vec = Mutex::new(vec![1, 2, 3]);
for number in mutex_vec.lock().unwrap().iter() {
dbg!(number);
}
}
```
However, the lint should be triggered when we clone the vector. In this case, the iterator does not hold any reference to the locked data.
```diff
- for number in mutex_vec.lock().unwrap().iter() {
+ for number in mutex_vec.lock().unwrap().clone().iter() {
```
Unfortunately, it seems that regions on the types of local variables are mostly erased (`ReErased`) in the late lint pass. So it is hard to tell if the final expression has a lifetime relevant to the value with a significant drop.
In this PR, I try to make a best-effort guess based on the function signatures. To avoid false positives, no lint is issued if the result is uncertain. I'm not sure if this is acceptable or not, so any comments are welcome.
Fixes https://github.com/rust-lang/rust-clippy/issues/8987
changelog: [`significant_drop_in_scrutinee`]: Trigger lint only if lifetime allows early significant drop.
r? `@flip1995`
feat: `Quick Fix` for `bare URLs`
closes#12835.
*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog: [`clippy::doc_markdown`]: `Quick Fix` for `bare URLs`
fulfill expectations in `check_partial_eq_without_eq`
This is a followup to #12804, fixing a similar issue for `derive_partial_eq_without_eq` by using `span_lint_hir_and_then` instead of `span_lint_and_sugg`.
Additionally tests for both `#[allow(clippy::derive_partial_eq_without_eq)]` and `#[expect(clippy::derive_partial_eq_without_eq)]` are added.
changelog:[`derive_partial_eq_without_eq`]: fulfill expectations
For restriction lints, replace “Why is this bad?” with “Why restrict this?”
The `restriction` group contains many lints which are not about necessarily “bad” things, but style choices — perhaps even style choices which contradict conventional Rust style — or are otherwise very situational. This results in silly wording like “Why is this bad? It isn't, but ...”, which I’ve seen confuse and distress a newcomer at least once.
To improve this situation, this PR replaces the “Why is this bad?” section heading with “Why restrict this?”, for most, but not all, restriction lints. I left alone the ones whose placement in the restriction group is more incidental.
In order to make this make sense, I had to remove the “It isn't, but” texts from the contents of the sections. Sometimes further changes were needed, or there were obvious fixes to make, and I went ahead and made those changes without attempting to split them into another commit, even though many of them are not strictly necessary for the “Why restrict this?” project; it seemed to me that it was more valuable to grab the low-hanging fruit than to be careful about it.
changelog: rephrased the documentation of `restriction` lints for clarity about their nature