We now check if the linted `Expr` is inside an `ItemKind::Static`, which can't take the suggested `Box<[...]`. I _think_ this is the correct fix for #9460
Auto merge of #9448 - Alexendoo:large-enum-variant-u128, r=Manishearth
Replace u128 with u64 in large_enum_variant uitest
A u128 has [an 8 byte alignment on x86](https://github.com/rust-lang/rust/issues/54341), but a 16 byte alignment on aarch64 which changes the size of the enums due to extra padding. This means the test fails on aarch64
Auto merge of #9446 - mikerite:fix-9431-2, r=giraffate
Fix `range_{plus,minus}_one` bad suggestions
Fixes #9431.
The current `range_plus_one` and `range_minus_one` suggestions are completely incorrect when macros are involved.
This commit resolves this by disabling the lints for any range expression that is expanded from a macro. The reasons for this are that it is very difficult to create a correct suggestion in this case and that false negatives are less important for pedantic lints.
changelog: Fix `range_{plus,minus}_one` bad suggestions
Michael Wright [Thu, 8 Sep 2022 18:04:43 +0000 (20:04 +0200)]
Fix `range_{plus,minus}_one` bad suggestions
Fixes #9431.
The current `range_plus_one` and `range_minus_one` suggestions
are completely incorrect when macros are involved.
This commit resolves this by disabling the lints for any range
expression that is expanded from a macro. The reasons for this
are that it is very difficult to create a correct suggestion in
this case and that false negatives are less important for
pedantic lints.
Fixes https://github.com/rust-lang/rust-clippy/issues/9307 and makes the `arithmetic` lint behave like `integer_arithmetic`.
It is worth noting that literal integers of a binary operation (`1 + 1`, `i32::MAX + 1`), **regardless if they are in a constant environment**, won't trigger the lint. Assign operations also have similar reasoning.
changelog: Consider literals in the arithmetic lint
Auto merge of #101241 - camsteffen:refactor-binding-annotations, r=cjgillot
`BindingAnnotation` refactor
* `ast::BindingMode` is deleted and replaced with `hir::BindingAnnotation` (which is moved to `ast`)
* `BindingAnnotation` is changed from an enum to a tuple struct e.g. `BindingAnnotation(ByRef::No, Mutability::Mut)`
* Associated constants added for convenience `BindingAnnotation::{NONE, REF, MUT, REF_MUT}`
One goal is to make it more clear that `BindingAnnotation` merely represents syntax `ref mut` and not the actual binding mode. This was especially confusing since we had `ast::BindingMode`->`hir::BindingAnnotation`->`thir::BindingMode`.
I wish there were more symmetry between `ByRef` and `Mutability` (variant) naming (maybe `Mutable::Yes`?), and I also don't love how long the name `BindingAnnotation` is, but this seems like the best compromise. Ideas welcome.
Suggest `Entry::or_default` for `Entry::or_insert(Default::default())`
Unlike past similar work done in #6228, expand the existing `or_fun_call`
lint to detect `or_insert` calls with a `T::new()` or `T::default()`
argument, much like currently done for `unwrap_or` calls. In that case,
suggest the use of `or_default`, which is more idiomatic.
Note that even with this change, `or_insert_with(T::default)` calls
aren't detected as candidates for `or_default()`, in the same manner
that currently `unwrap_or_else(T::default)` calls aren't detected as
candidates for `unwrap_or_default()`.
Also, as a nearby cleanup, change `KNOW_TYPES` from `static` to `const`,
since as far as I understand it's preferred (should Clippy have a lint
for that?).
Addresses #3812.
*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog: [`or_fun_call`]: Suggest `Entry::or_default` for `Entry::or_insert(Default::default())`
relrelb [Tue, 16 Aug 2022 20:26:03 +0000 (23:26 +0300)]
Suggest `Entry::or_default` for `Entry::or_insert(Default::default())`
Unlike past similar work done in #6228, expand the existing `or_fun_call`
lint to detect `or_insert` calls with a `T::new()` or `T::default()`
argument, much like currently done for `unwrap_or` calls. In that case,
suggest the use of `or_default`, which is more idiomatic.
Note that even with this change, `or_insert_with(T::default)` calls
aren't detected as candidates for `or_default()`, in the same manner
that currently `unwrap_or_else(T::default)` calls aren't detected as
candidates for `unwrap_or_default()`.
Also, as a nearby cleanup, change `KNOW_TYPES` from `static` to `const`,
since as far as I understand it's preferred (should Clippy have a lint
for that?).
Auto merge of #9424 - mikerite:fix-9351-4, r=xFrednet
Fix `unnecessary_to_owned` false positive
Fixes #9351.
Note that this commit reworks that fix for #9317. The change
is to check that the type implements `AsRef<str>` before regarding
`to_string` as an equivalent of `to_owned`. This was suggested
by Jarcho in the #9317 issue comments.
The benefit of this is that it moves some complexity out of
`check_other_call_arg` and simplifies the module as a whole.
changelog: FP: [`unnecessary_to_owned`]: No longer lints, if type change would cause errors in the caller function
Michael Wright [Sat, 3 Sep 2022 15:00:44 +0000 (17:00 +0200)]
Fix `unnecessary_to_owned` false positive
Fixes #9351.
Note that this commit reworks that fix for #9317. The change
is to check that the type implements `AsRef<str>` before regarding
`to_string` as an equivalent of `to_owned`. This was suggested
by Jarcho in the #9317 issue comments.
The benefit of this is that it moves some complexity out of
`check_other_call_arg` and simplifies the module as a whole.
Auto merge of #9400 - lukaslueg:approx_large_enum, r=llogiq
Use `approx_ty_size` for `large_enum_variant`
This builds upon #9373 to use the approximate size of each variant for `large_enum_variant`. This allows us to lint in situations where an `enum` contains generics but is still guaranteed to have a large variant on an at-least basis, e.g. with `(T, [u8; 512])`.
* I've changed the wording from "is ... bytes" to "contains at least" because
* the size is now an approximate lower bound (e.g. `512` in the example above). The actual size is larger due to `T`, including due to `T`'s memory layout.
* the discriminant is not taken into account in the message. This comes up with variants like `A(T)`, which are "is at least 0 bytes" otherwise, which may be misleading.
* If the second-largest variant has no fields, there is a special case "carries no data" instead of "is at least 0 bytes".
* A variant like `A(T)` is "at least 0 bytes", which is technically true, yet we don't distinguish between "indeterminate" and truly "ZST".
* The generics-tests that were there before now lint while they didn't lint before. AFAICS this is correct.
I guess the above is correct-ish. However, I use the `SubstsRef` that I got via `cx.tcx.type_of(item.def_id)` to solve for generics in the variants. Is this even applicable, since we start from an - [ ] `ItemKind`?
Auto merge of #9418 - lukaslueg:issue9415, r=llogiq
Fix `mut_mutex_lock` when Mutex is behind immutable deref
I *think* the problem here is the `if let ty::Ref(_, _, Mutability::Mut) = cx.typeck_results().expr_ty(recv).kind()` line tries to check if the `Mutex` can be mutably borrowed (there already is a test for `Arc<Mutex<_>>`), but gets bamboozled by the `&mut Arc` indirection. And I *think* checking the deref-adjustment to filter immutable-adjust (the deref through the `Arc`, starting from `&mut Arc`) is the correct fix.
Fixes #9415
changelog: Fix `mut_mutex_lock` when Mutex is behind immutable deref
Auto merge of #9417 - Jarcho:ice_9414, r=Alexendoo
Don't use `hir_ty_to_ty` in `result_large_err`
fixes #9414
This occurs starting with 2022-09-01. I checked that this does fix the ICE on rust-lang/rust@9353538. Not sure which pr caused the late-bound region to leak through `hir_ty_to_ty`.
Auto merge of #9412 - xFrednet:jst-r-bool-to-int-lint, r=xFrednet
New lint `bool_to_int_with_if`
This is a rebased version of https://github.com/rust-lang/rust-clippy/pull/9086 I could sadly not push directly push to the PR branch as it's protected.
The lint implementation comes from `@jst-r.` Thank you for the work you put into this :)
Auto merge of #9404 - lukaslueg:issue9402, r=giraffate
Fix `suboptimal_float` not linting on `{const}.powf({const})`
There used to be an early return if the receiver was an effective const but the method was not linted, not taking into account later cases where the receiver and the arguments are both effective consts for different methods. Removed the early return.
Fixes #9402
Fixes #9201
changelog: Fix `suboptimal_flops`, `imprecise_flops` not linting on `{const}.powf({const})` et al
bors [Wed, 31 Aug 2022 21:45:18 +0000 (21:45 +0000)]
Auto merge of #101249 - matthiaskrgr:rollup-wahnoz8, r=matthiaskrgr
Rollup of 10 pull requests
Successful merges:
- #100787 (Pretty printing give proper error message without panic)
- #100838 (Suggest moving redundant generic args of an assoc fn to its trait)
- #100844 (migrate rustc_query_system to use SessionDiagnostic)
- #101140 (Update Clippy)
- #101161 (Fix uintended diagnostic caused by `drain(..)`)
- #101165 (Use more `into_iter` rather than `drain(..)`)
- #101229 (Link “? operator” to relevant chapter in The Book)
- #101230 (lint: avoid linting diag functions with diag lints)
- #101236 (Avoid needless buffer zeroing in `std::sys::windows::fs`)
- #101240 (Fix a typo on `wasm64-unknown-unknown` doc)
bors [Tue, 30 Aug 2022 18:20:45 +0000 (18:20 +0000)]
Auto merge of #9373 - lukaslueg:result_large_err, r=Alexendoo
Initial implementation `result_large_err`
This is a shot at #6560, #4652, and #3884. The lint checks for `Result` being returned from functions/methods where the `Err` variant is larger than a configurable threshold (the default of which is 128 bytes). There has been some discussion around this, which I'll try to quickly summarize:
* A large `Err`-variant may force an equally large `Result` if `Err` is actually bigger than `Ok`.
* There is a cost involved in large `Result`, as LLVM may choose to `memcpy` them around above a certain size.
* We usually expect the `Err` variant to be seldomly used, but pay the cost every time.
* `Result` returned from library code has a high chance of bubbling up the call stack, getting stuffed into `MyLibError { IoError(std::io::Error), ParseError(parselib::Error), ...}`, exacerbating the problem.
This PR deliberately does not take into account comparing the `Ok` to the `Err` variant (e.g. a ratio, or one being larger than the other). Rather we choose an absolute threshold for `Err`'s size, above which we warn. The reason for this is that `Err`s probably get `map_err`'ed further up the call stack, and we can't draw conclusions from the ratio at the point where the `Result` is returned. A relative threshold would also be less predictable, while not accounting for the cost of LLVM being forced to generate less efficient code if the `Err`-variant is _large_ in absolute terms.
We lint private functions as well as public functions, as the perf-cost applies to in-crate code as well.
In order to account for type-parameters, I conjured up `fn approx_ty_size`. The function relies on `LateContext::layout_of` to compute the actual size, and in case of failure (e.g. due to generics) tries to come up with an "at least size". In the latter case, the size of obviously wrong, but the inspected size certainly can't be smaller than that. Please give the approach a heavy dose of review, as I'm not actually familiar with the type-system at all (read: I have no idea what I'm doing).
The approach does, however flimsy it is, allow us to successfully lint situations like
// We know `UnionError<T>` will be at least 512 bytes, no matter what `T` is
pub fn param_large_union<T: Copy>() -> Result<(), UnionError<T>> {
Ok(())
}
```
I've given some refactoring to `functions/result_unit_err.rs` to re-use some bits. This is also the groundwork for #6409
The default threshold is 128 because of https://github.com/rust-lang/rust-clippy/issues/4652#issue-505670554
`lintcheck` does not trigger this lint for a threshold of 128. It does warn for 64, though.
The suggestion currently is the following, which is just a placeholder for discussion to be had. I did have the computed size in a `span_label`. However, that might cause both ui-tests here and lints elsewhere to become flaky wrt to their output (as the size is platform dependent).
```
error: the `Err`-variant returned via this `Result` is very large
--> $DIR/result_large_err.rs:36:34
|
LL | pub fn param_large_error<R>() -> Result<(), (u128, R, FullyDefinedLargeError)> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The `Err` variant is unusually large, at least 128 bytes
```
Jason Newcomb [Tue, 30 Aug 2022 04:33:56 +0000 (00:33 -0400)]
Fix the order of `trait_duplication_in_bounds`
* Emit the lint in source order
* Make suggestions with multiple traits be in source order rather than alphabetical
bors [Mon, 29 Aug 2022 18:07:50 +0000 (18:07 +0000)]
Auto merge of #9247 - clubby789:raw_slice_pointer_cast, r=Alexendoo
New lint: Raw slice pointer cast
Adds a lint to check for a raw slice being created and cast back to a pointer, suggesting `ptr::slice_from_raw_parts`, to identify UB such as https://github.com/SimonSapin/rust-typed-arena/pull/54.
```
changelog: [`cast_slice_from_raw_parts`]: Add lint to check for `slice::from_raw_parts(.., ..) as *const _`
```
bors [Sun, 28 Aug 2022 10:59:16 +0000 (10:59 +0000)]
Auto merge of #9389 - lukaslueg:penmacro, r=llogiq
Don't lint literal `None` from expansion
This addresses https://github.com/rust-lang/rust-clippy/pull/9288#issuecomment-1229398524: If the literal `None` is from expansion, we never lint. This is correct because e.g. replacing the call to `option_env!` with whatever that macro expanded to at the time of linting is certainly wrong.
changelog: Don't lint [`partialeq_to_none`] for macro-expansions