new lint: `eager_transmute`
A small but still hopefully useful lint that looks for patterns such as `(x < 5).then_some(transmute(x))`.
This is almost certainly wrong because it evaluates the transmute eagerly and can lead to surprises such as the check being completely removed and always evaluating to `Some` no matter what `x` is (it is UB after all when the integer is not a valid bitpattern for the transmuted-to type). [Example](https://godbolt.org/z/xoY34fPzh).
The user most likely meant to use `then` instead.
I can't remember where I saw this but this is inspired by a real bug that happened in practice.
This could probably be a correctness lint?
changelog: new lint: [`eager_int_transmute`]
Return with a question mark was triggered in situations where the `?`
desuraging was performing error conversion via `Into`/`From`.
The desugared `?` produces a match over an expression with type
`std::ops::ControlFlow<B,C>` with `B:Result<Infallible, E:Error>` and
`C:Result<_, E':Error>`, and the arms perform the conversion. The patch
adds another check in the lint that checks that `E == E'`. If `E == E'`,
then the `?` is indeed unnecessary.
changelog: False Positive: `needless_return_with_question_mark` when
implicit Error Conversion occurs.
New lints `iter_filter_is_some` and `iter_filter_is_ok`
Adds a pair of lints that check for cases of an iterator over `Result` and `Option` followed by `filter` without being followed by `map` as that is covered already by a different, specialized lint.
Fixes#11843
PS, I also made some minor documentations fixes in a case where a double tick (`) was included.
---
changelog: New Lint: [`iter_filter_is_some`]
[#12004](https://github.com/rust-lang/rust/pull/12004)
changelog: New Lint: [`iter_filter_is_ok`]
[#12004](https://github.com/rust-lang/rust/pull/12004)
Make closures carry their own ClosureKind
Right now, we use the "`movability`" field of `hir::Closure` to distinguish a closure and a coroutine. This is paired together with the `CoroutineKind`, which is located not in the `hir::Closure`, but the `hir::Body`. This is strange and redundant.
This PR introduces `ClosureKind` with two variants -- `Closure` and `Coroutine`, which is put into `hir::Closure`. The `CoroutineKind` is thus removed from `hir::Body`, and `Option<Movability>` no longer needs to be a stand-in for "is this a closure or a coroutine".
r? eholk
Do not consider `async { (impl IntoFuture).await }` as redundant
changelog: [`redundant_async_block`]: do not trigger on `IntoFuture` instances
Fix#11959
Move `uninhabited_references` to `nursery`
I think this lint has too many false positives and should be put in pedantic. See #11984 and #11985 for context.
The lint is already in beta and is causing trouble for us, so I would also like this PR to be backported to beta as well.
changelog: Moved [`uninhabited_references`] to `nursery` (Now allow-by-default)
[#11997](https://github.com/rust-lang/rust-clippy/pull/11997)
(Check if this has been backported)
Fixes#11984.
[`question_mark`]: also trigger on `return` statements
This fixes the false negative mentioned in #11993: the lint only used to check for `return` expressions, and not a statement containing a `return` expression (doesn't close the issue tho since there's still a useful suggestion that we could make, which is to suggest `.ok_or()?`/`.ok_or_else()?` for `else { return Err(..) }`)
changelog: [`question_mark`]: also trigger on `return` statements
Clairify `ast::PatKind::Struct` presese of `..` by using an enum instead of a bool
The bool is mainly used for when a `..` is present, but it is also set on recovery to avoid errors. The doc comment not describes both of these cases.
See cee794ee98/compiler/rustc_parse/src/parser/pat.rs (L890-L897) for the only place this is constructed.
r? ``@compiler-errors``
fix typo in infinite loop lint
*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog: This fixes a small typo introduced in https://github.com/rust-lang/rust-clippy/pull/11829
Extend `UNNECESSARY_TO_OWNED` to handle `split`
Fixes https://github.com/rust-lang/rust-clippy/issues/9965.
When you have `to_string().split('a')` or equivalent, it'll suggest to remove the `to_owned`/`to_string` part.
r? `@flip1995`
changelog: Extend `UNNECESSARY_TO_OWNED` to handle `split`
Check whether out of bound when access a known length array with a constant index
fixes [Issue#11762](https://github.com/rust-lang/rust-clippy/issues/11762)
Issue#11762 points that `Array references with known length are not flagged when indexed out of bounds`.
To fix this problem, it is needed to add check for `Expr::Index`. We expand this issue include reference and direct accessing a array.
When we access a array with a constant index `off`, and already know the length `size`, if `off >= size`, these code will throw an error, instead rustc's lint checking them or runtime panic happening.
changelog: [`out_of_bound_indexing`]: Add check for illegal accessing known length array with a constant index
Add support for `for await` loops
This adds support for `for await` loops. This includes parsing, desugaring in AST->HIR lowering, and adding some support functions to the library.
Given a loop like:
```rust
for await i in iter {
...
}
```
this is desugared to something like:
```rust
let mut iter = iter.into_async_iter();
while let Some(i) = loop {
match core::pin::Pin::new(&mut iter).poll_next(cx) {
Poll::Ready(i) => break i,
Poll::Pending => yield,
}
} {
...
}
```
This PR also adds a basic `IntoAsyncIterator` trait. This is partly for symmetry with the way `Iterator` and `IntoIterator` work. The other reason is that for async iterators it's helpful to have a place apart from the data structure being iterated over to store state. `IntoAsyncIterator` gives us a good place to do this.
I've gated this feature behind `async_for_loop` and opened #118898 as the feature tracking issue.
r? `@compiler-errors`
Adds a pair of lints that check for cases of an iterator over `Result`
and `Option` followed by `filter` without being followed by `map` as
that is covered already by a different, specialized lint.
changelog: New Lint: [`iter_filter_is_some`]
changelog: New Lint: [`iter_filter_is_ok`]
New Lint: `result_filter_map` / Mirror of `option_filter_map`
Added the `Result` mirror of `option_filter_map`.
changelog: New Lint: [`result_filter_map`]
I had to move around some code because the function def was too long 🙃.
I have also added some pattern checks on `option_filter_map`
Add new `unconditional_recursion` lint
Currently, rustc `unconditional_recursion` doesn't detect cases like:
```rust
enum Foo {
A,
B,
}
impl PartialEq for Foo {
fn eq(&self, other: &Self) -> bool {
self == other
}
}
```
This is because the lint is currently implemented only for one level, and in the above code, `self == other` will then call `impl PartialEq for &T`, escaping from the detection. The fix for it seems to be a bit tricky (I started investigating potential solution to add one extra level of recursion [here](https://github.com/rust-lang/rust/compare/master...GuillaumeGomez:rust:trait-impl-recursion?expand=1) but completely broken at the moment).
I expect that this situation will remain for a while. In the meantime, I think it's acceptable to check it directly into clippy for the time being as a lot of easy cases like this one can be easily checked (next I plan to extend it to cover other traits like `ToString`).
changelog: Add new `unconditional_recursion` lint
Added the `Result` mirror of `option_filter_map` to catch
```
.into_iter().filter(Result::is_ok).map(Result::unwrap)
```
changelog: New Lint: [`result_filter_map`]
Co-authored-by: Alex Macleod <alex@macleod.io>
Uplift `TypeAndMut` and `ClosureKind` to `rustc_type_ir`
Uplifts `TypeAndMut` and `ClosureKind`
I know I said I was just going to get rid of `TypeAndMut` (https://github.com/rust-lang/types-team/issues/124) but I think this is much simpler, lol
r? `@jackh726` or `@lcnr`
Fix binder handling in `unnecessary_to_owned`
fixes#11952
The use of `rebind` instead of `EarlyBinder::bind` isn't technically needed, but it is the semantically correct operation.
changelog: None
[`doc_markdown`] Recognize words followed by empty parentheses `()` for quoting
*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog: [`doc_markdown`] Recognize words followed by empty parentheses for quoting, e.g. `func()`.
---
Developers often write function/method names with trailing `()`, but `doc_markdown` lint did not consider that.
Old clippy suggestion was not very good:
```patch
-/// There is no try (do() or do_not()).
+/// There is no try (do() or `do_not`()).
```
New behavior recognizes function names such as `do()` even they contain no `_`/`::`; and backticks are suggested outside of the `()`:
```patch
-/// There is no try (do() or do_not()).
+/// There is no try (`do()` or `do_not()`).
```
Useless vec false positive
changelog: [`useless_vec`]: fix false positive in macros.
fixes#11861
We delay the emission of `useless_vec` lints to the check_crate_post stage, which allows us to effectively undo lints if we find that a `vec![]` expression is being used multiple times after macro expansion.
new lint to detect infinite loop
closes: #11438
changelog: add new lint to detect infinite loop
~*I'll change the lint name*~. Should I name it `infinite_loop` or `infinite_loops` is fine? Ahhhh, English is hard...
Renamings:
- find -> opt_hir_node
- get -> hir_node
- find_by_def_id -> opt_hir_node_by_def_id
- get_by_def_id -> hir_node_by_def_id
Fix rebase changes using removed methods
Use `tcx.hir_node_by_def_id()` whenever possible in compiler
Fix clippy errors
Fix compiler
Apply suggestions from code review
Co-authored-by: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Add FIXME for `tcx.hir()` returned type about its removal
Simplify with with `tcx.hir_node_by_def_id`
Add lint against ambiguous wide pointer comparisons
This PR is the resolution of https://github.com/rust-lang/rust/issues/106447 decided in https://github.com/rust-lang/rust/issues/117717 by T-lang.
## `ambiguous_wide_pointer_comparisons`
*warn-by-default*
The `ambiguous_wide_pointer_comparisons` lint checks comparison of `*const/*mut ?Sized` as the operands.
### Example
```rust
let ab = (A, B);
let a = &ab.0 as *const dyn T;
let b = &ab.1 as *const dyn T;
let _ = a == b;
```
### Explanation
The comparison includes metadata which may not be expected.
-------
This PR also drops `clippy::vtable_address_comparisons` which is superseded by this one.
~~One thing: is the current naming right? `invalid` seems a bit too much.~~
Fixes https://github.com/rust-lang/rust/issues/117717
uninhabited_reference: new lint
Close#11851
The lint is implemented on function parameters and return types, as this is the place where the risk of exchanging references to uninhabited types is the highest. Other constructs, such as in a local variable,
would require the use of `unsafe` and will clearly be done on purpose.
changelog: [`uninhabited_reference`]: new lint
This is an extension of the previous commit. It means the output of
something like this:
```
stringify!(let a: Vec<u32> = vec![];)
```
goes from this:
```
let a: Vec<u32> = vec![] ;
```
With this PR, it now produces this string:
```
let a: Vec<u32> = vec![];
```
detects redundant imports that can be eliminated.
for #117772 :
In order to facilitate review and modification, split the checking code and
removing redundant imports code into two PR.
Introduce support for `async gen` blocks
I'm delighted to demonstrate that `async gen` block are not very difficult to support. They're simply coroutines that yield `Poll<Option<T>>` and return `()`.
**This PR is WIP and in draft mode for now** -- I'm mostly putting it up to show folks that it's possible. This PR needs a lang-team experiment associated with it or possible an RFC, since I don't think it falls under the jurisdiction of the `gen` RFC that was recently authored by oli (https://github.com/rust-lang/rfcs/pull/3513, https://github.com/rust-lang/rust/issues/117078).
### Technical note on the pre-generator-transform yield type:
The reason that the underlying coroutines yield `Poll<Option<T>>` and not `Poll<T>` (which would make more sense, IMO, for the pre-transformed coroutine), is because the `TransformVisitor` that is used to turn coroutines into built-in state machine functions would have to destructure and reconstruct the latter into the former, which requires at least inserting a new basic block (for a `switchInt` terminator, to match on the `Poll` discriminant).
This does mean that the desugaring (at the `rustc_ast_lowering` level) of `async gen` blocks is a bit more involved. However, since we already need to intercept both `.await` and `yield` operators, I don't consider it much of a technical burden.
r? `@ghost`
never_patterns: Parse match arms with no body
Never patterns are meant to signal unreachable cases, and thus don't take bodies:
```rust
let ptr: *const Option<!> = ...;
match *ptr {
None => { foo(); }
Some(!),
}
```
This PR makes rustc accept the above, and enforces that an arm has a body xor is a never pattern. This affects parsing of match arms even with the feature off, so this is delicate. (Plus this is my first non-trivial change to the parser).
~~The last commit is optional; it introduces a bit of churn to allow the new suggestions to be machine-applicable. There may be a better solution? I'm not sure.~~ EDIT: I removed that commit
r? `@compiler-errors`
Add a function to check whether binary oprands are nontrivial
fixes [#issue11885](https://github.com/rust-lang/rust-clippy/issues/11885)
It's hard to check whether operator is overrided through context of lint.
So, assume non-trivial structure like tuple, array or sturt, using a overrided binary operator in this lint, which might cause a side effict.
This is not detected before.
Althrough this might weaken the ability of this lint, it may more useful than before. Maybe this lint will cause an error, but now, it not. And assuming side effect of non-trivial structure with operator is not a bad thing, right?
changelog: Fix: [`no_effect`] check if binary operands are nontrivial
fix(ptr_as_ptr): handle `std::ptr::null{_mut}`
close rust-lang#11066
close rust-lang#11665
close rust-lang#11911
*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog: [`ptr_as_ptr`]: handle `std::ptr::null` and `std::ptr::null_mut`
needless_borrows_for_generic_args: Handle when field operand impl Drop
Before this fix, the lint had a false positive, namely when a reference was taken to a field when the field operand implements a custom Drop. The compiler will refuse to partially move a type that implements Drop, because that would put the type in a weird state.
## False Positive Example (Fixed)
```rs
struct CustomDrop(String);
impl Drop for CustomDrop {
fn drop(&mut self) {}
}
fn check_str<P: AsRef<str>>(_to: P) {}
fn test() {
let owner = CustomDrop(String::default());
check_str(&owner.0); // Don't lint. `owner` can't be partially moved because it impl Drop
}
```
changelog: [`needless_borrows_for_generic_args`]: Handle when field operand impl Drop
docs(explicit_write): add missing backtick to complete code snippet
close#11918
*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog: [`explicit_write`]: add missing backtick to document to complete code snippet
Update regex-syntax to support new word boundry assertions
From the regex v1.10.0 release notes [1]:
This is a new minor release of regex that adds support for start
and end word boundary assertions. [...]
The new word boundary assertions are:
• \< or \b{start}: a Unicode start-of-word boundary (\W|\A
on the left, \w on the right).
• \> or \b{end}: a Unicode end-of-word boundary (\w on the
left, \W|\z on the right)).
• \b{start-half}: half of a Unicode start-of-word boundary
(\W|\A on the left).
• \b{end-half}: half of a Unicode end-of-word boundary
(\W|\z on the right).
[1]: https://github.com/rust-lang/regex/blob/master/CHANGELOG.md#1100-2023-10-09
changelog: [`regex`]: add support for start and end word boundary assertions ("\<", "\b{start}", etc.) introduced in regex v0.10
Simpfy code of `is_operator_overrided`, directly use `is_method_call` to
check
if operator is overrided, at least one oprand of binary-expr must be ADT-type
So no need to check type of lhs and rhs
Check whether operator is overrided with a `struct` operand.
The struct here refers to `struct`, `enum`, `union`.
Add and fix test for `no_effect` lint.
From the regex v1.10.0 release notes [1]:
This is a new minor release of regex that adds support for start
and end word boundary assertions. [...]
The new word boundary assertions are:
• \< or \b{start}: a Unicode start-of-word boundary (\W|\A
on the left, \w on the right).
• \> or \b{end}: a Unicode end-of-word boundary (\w on the
left, \W|\z on the right)).
• \b{start-half}: half of a Unicode start-of-word boundary
(\W|\A on the left).
• \b{end-half}: half of a Unicode end-of-word boundary
(\W|\z on the right).
[1]: https://github.com/rust-lang/regex/blob/master/CHANGELOG.md#1100-2023-10-09
expending lint [`blocks_in_if_conditions`] to check match expr as well
closes: #11814
changelog: rename lint `blocks_in_if_conditions` to [`blocks_in_conditions`] and expand it to check blocks in match scrutinees
[`missing_asserts_for_indexing`]: accept length equality checks
Fixes#11835
The lint now allows indexing with indices 0 and 1 when an `assert!(x.len() == 2);` is found.
(Also fixed a typo in the doc example)
changelog: [`missing_asserts_for_indexing`]: accept len equality checks as a valid assertion
Before this fix, the lint had a false positive, namely when a reference
was taken to a field when the field operand implements a custom Drop.
The compiler will refuse to partially move a type that implements Drop,
because that would put the operand in a weird state. See added
regression test.
`option_if_let_else`: do not trigger on expressions returning `()`
Fix#11893
Trigerring on expressions returning `()` uses the arguments of the `map_or_else()` rewrite only for their side effects. This does lead to code which is harder to read than the original.
changelog: [`option_if_let_else`]: do not trigger on unit expressions
add lint against unit tests in doctests
During RustLab, Alice Ryhl brought to my attention that the Andoid team stumbled over the fact that if one attempts to write a unit test within a doctest, it will be summarily ignored. So this lint should help people wondering why their tests won't run.
---
changelog: New lint: [`test_attr_in_doctest`]
[#11872](https://github.com/rust-lang/rust-clippy/pull/11872)
Fix#11893
Trigerring on expressions returning `()` uses the arguments of the
`map_or_else()` rewrite only for their side effects. This does lead
to code which is harder to read than the original.
[`redundant_guards`]: catch `is_empty`, `starts_with` and `ends_with` on slices and `str`s
Fixes#11807
Few things worth mentioning:
- Taking `snippet`s is now done at callsite, instead of passing a span and doing it in `emit_redundant_guards`. This is because we now need custom suggestion strings in certain places, like `""` for `str::is_empty`.
- This now uses `snippet` instead of `snippet_with_applicability`. I don't think this really makes any difference for `MaybeIncorrect`, though?
- This could also lint byte strings, as they're of type `&[u8; N]`, but that can be ugly so I decided to leave it out for now
changelog: [`redundant_guards`]: catch `str::is_empty`, `slice::is_empty`, `slice::starts_with` and `slice::ends_with`
Add `never_patterns` feature gate
This PR adds the feature gate and most basic parsing for the experimental `never_patterns` feature. See the tracking issue (https://github.com/rust-lang/rust/issues/118155) for details on the experiment.
`@scottmcm` has agreed to be my lang-team liaison for this experiment.
[`redundant_closure_call`]: avoid duplicated `async` keyword when triggering on closure that returns `async` block
close#11357
----
*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog: [`redundant_closure_call`]: avoid duplicated `async` keyword when triggering on closure that returns `async` block
- Rename them both `as_str`, which is the typical name for a function
that returns a `&str`. (`to_string` is appropriate for functions
returning `String` or maybe `Cow<'a, str>`.)
- Change `UnOp::as_str` from an associated function (weird!) to a
method.
- Avoid needless `self` dereferences.
Don't suggest `a.mul_add(b, c)` if parameters are not float
clippy::suboptimal_flops used to not check if the second parameter to f32/f64.mul_add() was float. Since the method is only defined to take `Self` as parameters, the suggestion was wrong.
Fixes#11831
changelog: [`suboptimal_float`]: Don't suggest `a.mul_add(b, c)` if parameters are not f32/f64
[`ptr_arg`]: recognize methods that also exist on slices
Fixes#11816
Not a new lint, just a very small improvement to the existing `ptr_arg` lint which would have caught the linked issue.
The problem was that the lint checks if a `Vec`-specific method was called, that is, if the receiver is `Vec<_>`.
This is the case for `len` and `is_empty`, however these methods also exist on slices so we can still lint there.
This logic exists in a different lint, so we can just reuse that here.
Interestingly, there was even a comment up top that explained what it should have been doing, but the logic for it just wasn't there?
changelog: [`ptr_arg`]: recognize methods that also exist on slices
<sub>Also, this is my 100th PR to clippy 🎉 </sub>
`manual_try_fold`: check that `fold` is really `Iterator::fold`
Fix#11876
changelog: [`manual_try_fold`]: suggest using `try_fold` only for `Iterator::fold` uses
Move `implied_bounds_in_impls` back to complexity
This lint was originally in the complexity category when I PR'd it. It was then moved to nursery by me due to a number of issues (a false positive, an invalid suggestion and an ICE), but that was probably an overreaction and all of the issues were fixed quickly after.
This is a useful lint imo and there hasn't been any issues with it in a few months, so I say we should give it another try and move it back to complexity.
I did a lintcheck run on the top 400 crates and all of them are legitimate, with 18 warnings. Most of them are from anstyle having a `impl Display + Copy + Clone` return type, or the bitvec crate with a return type like `impl Iterator + DoubleEndedIterator`.
changelog: Move [`implied_bounds_in_impls`] to `complexity` (Now warn-by-default)
[#11867](https://github.com/rust-lang/rust-clippy/pull/11867)
Create new lint `option_map_or_err_ok`
Fixes#10045.
For the following code:
```rust
let opt = Some(1);
opt.map_or(Err("error"), Ok);
```
It suggests to instead write:
```rust
let opt = Some(1);
opt.ok_or("error");
```
r? `@flip1995`
changelog: Create new lint `option_map_or_err_ok`
suggest alternatives to iterate an array of ranges
works towards #7125
changelog: [`single_element_loop`]: suggest better syntax when iterating over an array of a single range
`@thinkerdreamer` and myself worked on this issue during a workshop by `@llogiq` at the RustLab 2023 conference. It is our first contribution to clippy.
When iterating over an array of only one element, _which is a range_, our change suggests to replace the array with the contained range itself. Additionally, a hint is printed stating that the user probably intended to iterate over the range and not the array. If the single element in the array is not a range, the previous suggestion in the form of `let {pat_snip} = {prefix}{arg_snip};{block_str}`is used.
This change lints the array with the single range directly, so any prefixes or suffixes are covered as well.
Nit re `matches!` formatting
I think formatting `matches!` with `if` guards is [still unsupported](https://github.com/rust-lang/rustfmt/issues/5547), which is probably why this was missed.
changelog: none
[`deprecated_semver`]: Allow `#[deprecated(since = "TBD")]`
"TBD" is allowed by rustdoc, saying that it will be deprecated in a future version. rustc will also not actually warn on it.
I found this while checking the rust-lang/rust with clippy.
changelog: [`deprecated_semver`]: allow using `since = "TBD"`
[`missing_asserts_for_indexing`]: work with bodies instead of blocks separately
Fixes#11856
Before this change, this lint would check blocks independently of each other, which means that it misses `assert!()`s from parent blocks.
```rs
// check_block
assert!(x.len() > 1);
{
// check_block
// no assert here
let _ = x[0] + x[1];
}
```
This PR changes it to work with bodies rather than individual blocks. That means that a function will be checked in one go and we can remember if an `assert!` occurred anywhere.
Eventually it would be nice to have a more control flow-aware analysis, possibly by rewriting it as a MIR lint, but that's more complicated and I wanted this fixed first.
changelog: [`missing_asserts_for_indexing`]: accept `assert!`s from parent blocks
Fix iter_kv_map false positive into_keys and into_values suggestion
fixes: #11752
changelog: [`iter_kv_map`]: fix false positive: Don't suggest `into_keys()` and `into_values()` if the MSRV is to low
[`needless_return_with_question_mark`]: don't lint if never type is used for coercion
Fixes#11616
When we have something like
```rs
let _x: String = {
return Err(())?;
};
```
we shouldn't suggest removing the `return` because the `!`-ness of `return` is used to coerce the enclosing block to some other type. That will lead to a typeck error without a diverging expression like `return`.
changelog: [`needless_return_with_question_mark`]: don't lint if `return`s never typed-ness is used for coercion
Split `doc.rs` up into a subdirectory
So, first, sorry for the bad diff. 😅
In #11798, `@flip1995` suggested splitting `doc.rs` up, much like how we have the `methods/`, `matches/`, `types/` subdirectories.
I agree with this, the file is getting bigger as we add more and more doc lints that it makes sense to do this refactoring.
This is purely an internal change that moves things around a bit.
(**EDIT:** depending on the outcome of https://github.com/rust-lang/rust-clippy/pull/11801#issuecomment-1816715615 , this may change the lint group name from `doc_markdoc` to `doc`).
I tried to not change any of the actual logic of the lints and as such some things weren't as easy to move to a separate file. So we still have some `span_lint*` calls in the `doc/mod.rs` file, which I think is fine. This is also the case in `methods/mod.rs`.
Also worth mentioning that the lints missing_errors_doc, missing_panics_doc, missing_safety_doc and unnecessary_safety_doc have a lot of the same logic so it didn't make much sense for each of these to be in their own file. Instead I just put them all in `missing_headers.rs`
I also added a bit of documentation to the involved `check_{attrs,doc}` methods.
changelog: none
Improve maybe misused cfg
Follow-up of the improvements that were suggested to me in https://github.com/rust-lang/rust-clippy/pull/11821:
* I unified the output to use the same terms.
* I updated the code to prevent creating a new symbol.
r? `@blyxyas`
changelog: [`maybe_misued_cfg`]: Output and code improvements
Verify Borrow<T> semantics for types that implement Hash, Borrow<str> and Borrow<[u8]>.
Fixes#11710
The essence of the issue is that types that implement Borrow<T> provide a facet or a representation of the underlying type. Under these semantics `hash(a) == hash(a.borrow())`.
This is a problem when a type implements `Borrow<str>`, `Borrow<[u8]>` and Hash, it is expected that the hash of all three types is identical. The problem is that the hash of [u8] is not the same as that of a String, even when the byte reference ([u8]) is derived from `.as_bytes()`
- [x] Followed [lint naming conventions][lint_naming]
- [x] Added passing UI tests (including committed `.stderr` file)
- [x] `cargo test` passes locally
- [x] Executed `cargo dev update_lints`
- [x] Added lint documentation
- [x] Run `cargo dev fmt`
---
- [x] Explanation of the issue in the code
- [x] Tests reproducing the issue
- [x] Lint rule and emission
---
changelog: New lint: [`impl_hash_borrow_with_str_and_bytes`]
[#11781](https://github.com/rust-lang/rust-clippy/pull/11781)
Implements a lint to prevent implementation of Hash, Borrow<str> and
Borrow<[u8]> as it breaks Borrow<T> "semantics". According to the book,
types that implement Borrow<A> and Borrow<B> must ensure equality of
borrow results under Eq,Ord and Hash.
> In particular Eq, Ord and Hash must be equivalent for borrowed and
owned values: x.borrow() == y.borrow() should give the same result as x == y.
In the same way, hash(x) == hash(x as Borrow<[u8]>) != hash(x as Borrow<str>).
changelog: newlint [`impl_hash_with_borrow_str_and_bytes`]
Fix typos in recent lint documentation.
Fixes typos and markup errors, and also makes the examples more realistic by hiding the `;`s so as not to visibly be discarding the computed value. Affected lints:
* `redundant_as_str`
* `unnecessary_map_on_constructor`
changelog: none
clippy::suboptimal_flops used to not check if the second parameter to f32/f64.mul_add() was float. Since the method is
only defined to take `Self` as paremters, the suggestion was wrong.
Fixes#11831
teach `eager_or_lazy` about panicky arithmetic operations
Fixes#9422Fixes#9814Fixes#11793
It's a bit sad that we have to do this because arithmetic operations seemed to me like the prime example where a closure would not be necessary, but this has "side effects" (changes behavior when going from lazy to eager) as some of these panic on overflow/underflow if compiled with `-Coverflow-checks` (which is the default in debug mode).
Given the number of backlinks in the mentioned issues, this seems to be a FP that is worth fixing, probably.
changelog: [`unnecessary_lazy_evaluations`]: don't lint if closure has panicky arithmetic operations
Extend `maybe_misused_cfg` lint over `cfg(test)`
Fixes#11240.
One thought I had is that we could use the levenshtein distance (of 1) to ensure this is indeed `test` that was targeted. But maybe it's overkill, not sure.
changelog: [`maybe_misused_cfg`]: Extend lint over `cfg(test)`
r? `@blyxyas`
Changelog for Rust 1.74 🎃
Roses are red,
Halloween is over,
Have you considered,
Buying a Mars rover?
---
### The cats of this release:
<img height=500 src="https://github.com/rust-lang/rust-clippy/assets/17087237/095bd32e-b5e3-41db-8f0f-bdef7ca1a6d0" alt="The cats of this Clippy release" />
<sub>The cat for the next release can be nominated in the comments</sub>
---
changelog: none
Change `if_same_then_else` to be a `style` lint
CC #3770
From https://github.com/rust-lang/rust-clippy/issues/3770#issuecomment-687565594 (`@flip1995):`
> Oh I thought I replied to this: I definitely see now that having this
> as a correctness lint might be the wrong categorization. What we might
> want to do is to just allow this lint, if there are comments in the
> arm bodies. But a good first step would be to downgrade this lint to
> style or complexity. I would vote for style since merging two arms is
> not always less complex.
changelog: [`if_same_then_else`]: Change to be a `style` lint
[`impl_trait_in_params`]: avoid ICE when function with `impl Trait` type has no parameters
Fixes#11803
If I'm reading the old code correctly, it was taking the span of the first parameter (without checking that it exists, which caused the ICE) and uses that to figure out where the generic parameter to insert should go (cc `@blyxyas` you wrote the lint, is that correct?).
This seemed equivalent to just `generics.span`, which doesn't require calculating the spans like that and simplifies it a fair bit
changelog: don't ICE when function has no parameters but generics have an `impl Trait` type
CC #3770
From https://github.com/rust-lang/rust-clippy/issues/3770#issuecomment-687565594 (@flip1995):
> Oh I thought I replied to this: I definitely see now that having this
> as a correctness lint might be the wrong categorization. What we might
> want to do is to just allow this lint, if there are comments in the
> arm bodies. But a good first step would be to downgrade this lint to
> style or complexity. I would vote for style since merging two arms is
> not always less complex.
Implement new lint `iter_over_hash_type`
Implements and fixes https://github.com/rust-lang/rust-clippy/issues/11788
This PR adds a new *restriction* lint `iter_over_hash_type` which prevents `Hash`-types (that is, `HashSet` and `HashMap`) from being used as the iterator in `for` loops.
The justification for this is because in `Hash`-based types, the ordering of items is not guaranteed and may vary between executions of the same program on the same hardware. In addition, it reduces readability due to the unclear iteration order.
The implementation of this lint also ensures the following:
- Calls to `HashMap::keys`, `HashMap::values`, and `HashSet::iter` are also denied when used in `for` loops,
- When this expression is used in procedural macros, it is not linted/denied.
changelog: add new `iter_over_hash_type` lint to prevent unordered iterations through hashed data structures
Fixes to `manual_let_else`'s divergence check
A few changes to the divergence check in `manual_let_else` and moves it the implementation to `clippy_utils` since it's generally useful:
* Handle internal `break` and `continue` expressions.
e.g. The first loop is divergent, but the second is not.
```rust
{
loop {
break 'outer;
};
}
{
loop {
break;
};
}
```
* Match rust's definition of divergence which is defined via the type system.
e.g. The following is not considered divergent by rustc as the inner block has a result type of `()`:
```rust
{
'a: {
panic!();
break 'a;
};
}
```
* Handle when adding a single semicolon would make the expression divergent.
e.g. The following would be a divergent if a semicolon were added after the `if` expression:
```rust
{ if panic!() { 0 } else { 1 } }
```
changelog: None
Lint `needless_borrow` and `explicit_auto_deref` on most union field accesses
Changes both lints to follow rustc's rules around auto-deref through `ManuallyDrop` union fields rather than just bailing on union fields.
changelog: [`needless_borrow`] & [`explicit_auto_deref`]: Lint on most union field accesses
Disable `vec_box` when using different allocators
Fixes#7114
This PR disables the `vec_box` lint when the `Box` and `Vec` use different allocators (but not when they use the same - custom - allocator).
For example - `Vec<Box<i32, DummyAllocator>>` will disable the lint, and `Vec<Box<i32, DummyAllocator>, DummyAllocator>` will not disable the lint.
In addition, the applicability of this lint has been changed to `Unspecified` due to the automatic fixes potentially breaking code such as the following:
```rs
fn foo() -> Vec<Box<i32>> { // -> Vec<i32>
vec![Box::new(1)]
}
```
It should be noted that the `if_chain->let-chains` fix has also been applied to this lint, so the diff does contain many changes.
changelog: disable `vec_box` lint when using nonstandard allocators
[`mod_module_files`] Don't emit lint for mod.rs in tests
fixes: #11775
current state: indiscriminately emits the lint for mod files in tests.
The following
```
tests/
common/
mod.rs
test.rs
```
is a common pattern for code shared across the tests and is suggested in the rust book. The change adds an additional check to verify that the mod file is not in tests.
changelog: Fix [`mod_module_files`]: false positive for mod files in tests folder
fixes: #11775
current state: indiscriminately emits the lint for mod files in tests.
The following
tests/
common/
mod.rs
test.rs
is a common pattern for code shared across the tests and is suggested in
the rust book. The change adds an additional check to verify that the
mod file is not in tests.
changelog: Fix [`mod_module_files`]: false positive for mod files in
tests folder
Fix `dbg_macro` semi span calculation
`span_including_semi` was using a `BytePos` to index into a file's source which happened to work because the root file of the test started at `BytePos` 0, it didn't work for other files
changelog: none
Most notably, this commit changes the `pub use crate::*;` in that file
to `use crate::*;`. This requires a lot of `use` items in other crates
to be adjusted, because everything defined within `rustc_span::*` was
also available via `rustc_span::source_map::*`, which is bizarre.
The commit also removes `SourceMap::span_to_relative_line_string`, which
is unused.
new lint: `unnecessary_fallible_conversions`
Closes#11577
A new lint that looks for calls such as `i64::try_from(1i32)` and suggests `i64::from(1i32)`. See lint description (and linked issue) for more details for why.
There's a tiny bit of overlap with the `useless_conversion` lint, in that the other one warns `T::try_from(T)` (i.e., fallibly converting to the same type), so this lint ignores cases like `i32::try_from(1i32)` to avoid emitting two warnings for the same expression.
Also, funnily enough, with this one exception, this lint would warn on exactly every case in the `useless_conversion_try` ui test that `useless_conversion` didn't cover (but never two warnings at the same time), which is neat. I did add an `#![allow]` though since we don't want interleaved warnings from multiple lints in the same uitest.
changelog: new lint: `unnecessary_fallible_conversions`
fix enum_variant_names depending lint depending on order
changelog: [`enum_variant_names`]: fix single word variants preventing lint of later variant pre/postfixed with the enum name
fixes#11494
Single word variants prevented checking the `check_enum_start` and `check_enum_end` for being run on later variants
Use multiple pushes in `vec_init_then_push` example
Makes the perf argument clearer, since a single push doesn't have unnecessary allocations compared to `vec![x]`
changelog: none
Remove internal feature from clippy_utils
It's only used to gate a few `const`s, removing the feature gate means it doesn't have to be recompiled when moving between a normal and `-F internal` build/test/etc
changelog: none
ignore lower-camel-case words in `doc_markdown`
This fixes#11568 by ignoring camelCase words starting with a lower case letter.
r? `@blyxyas`
---
changelog: none
move `read_zero_byte_vec` to nursery
I think the concerns in #9274 are valid, and we should move this to nursery while we're reworking this.
changelog: [`read_zero_byte_vec`] moved to nursery
Expand docs on clippy::todo
https://doc.rust-lang.org/nightly/core/macro.todo.html describes that `todo!()` is intended for explicitly unfinished code. Explain this, and mention `unimplemented!()` as an alternative.
Whilst we're here, improve the punctuation on the other lints.
changelog: [`todo`]: expand docs
Fix missing parenthesis in suboptimal floating point help
This fixes#11559 by adding a branch in the `Neg` implementation for `Sugg` that adds parentheses to keep precedence in order, then using that in the suggestion. I also removed some needless `.to_string()`s while I was at it.
---
changelog: none
[`iter_without_into_iter`]: fix papercuts in suggestion and restrict linting to exported types
See #11692 for more context.
tldr: the lint `iter_without_into_iter` has suggestions that don't compile, which imo isn't that problematic because it does have the appropriate `Applicability` that tells external tools that it shouldn't be auto-applied.
However there were some obvious "errors" in the suggestion that really should've been included in my initial PR adding the lint, which is fixed by this PR:
- `IntoIterator::into_iter` needs a `self` argument.
- `IntoIterator::Iter` associated type doesn't exist. This should've just been `Item`.
This still doesn't make it machine applicable, and the remaining things are imho quite non-trivial to implement, as I've explained in https://github.com/rust-lang/rust-clippy/issues/11692#issuecomment-1773886111.
I personally think it's fine to leave it there and let the user change the remaining errors when copy-pasting the suggestion (e.g. errors caused by lifetimes that were permitted in fn return-position but are not in associated types).
This is how many of our other lint suggestions already work.
Also, we now restrict linting to only exported types. This required moving basically all of the tests around since they were previously in the `main` function. Same for `into_iter_without_iter`. The git diff is a bit useless here...
changelog: [`iter_without_into_iter`]: fix papercuts in suggestion and restrict linting to exported types
(cc `@lopopolo,` figured I should mention you since you created the issue)
https://doc.rust-lang.org/nightly/core/macro.todo.html
describes that `todo!()` is intended for explicitly unfinished
code. Explain this, and mention `unimplemented!()` as an alternative.
Whilst we're here, improve the punctuation on the other lints.
Add `waker_clone_and_wake` lint to check needless `Waker` clones
Check for patterns of `waker.clone().wake()` and replace them with `waker.wake_by_ref()`.
An alternative name could be `waker_clone_then_wake`
changelog: [ `waker_clone_wake`]: new lint
Remove the `internal_warn` lint category
`LINT_AUTHOR` and `DUMP_HIR` can be removed since their corresponding lint passes are only used for side effects
The metadata collector lint can be made an `internal` lint since `clippy::internal` is set to deny when running the collector
Also renames some internal lints/passes
changelog: none
Set doc-tests to `no_run`
This excludes `should_panic` tests, those are still run to ensure they panic. Most of our other doc snippets don't gain much from being run though so this frees up a nice bit of CI time
It also fixes the occasional issue such as `foo.txt`s being created f942470ca7/clippy_lints/src/permissions_set_readonly_false.rs (L19)
changelog: none
suggest passing function instead of calling it in closure for [`option_if_let_else`]
fixes: #11429
changelog: suggest passing function instead of calling it in closure for [`option_if_let_else`]
Skip if_not_else lint for '!= 0'-style checks
Currently, clippy makes unhelpful suggestions such as this:
```
warning: unnecessary `!=` operation
--> src/vm.rs:598:36
|
598 | *destination = if source & 0x8000 != 0 { 0xFFFF } else { 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: change to `==` and swap the blocks of the `if`/`else`
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#if_not_else
= note: `-W clippy::if-not-else` implied by `-W clippy::pedantic`
```
Bit tests often take on the form `if foo & 0x1234 != 0 { … } else { … }`, and the `!= 0` part reads as "has any bits set". Therefore, this code already has the "correct" order, and shouldn't be changed.
This PR disables the lint for these cases, and in fact all cases where the condition is "foo is non-zero".
I did my homework:
- \[X] Followed [lint naming conventions][lint_naming] → Not applicable, this PR fixes an existing lint
- \[X] Added passing UI tests (including committed `.stderr` file) → Yes, `tests/ui/if_not_else_bittest.rs`
- \[X] `cargo test` passes locally
- \[X] Executed `cargo dev update_lints`
- \[X] Added lint documentation → Not applicable, this PR fixes an existing lint
- \[X] Run `cargo dev fmt`
changelog: Fix [`if_not_else`] false positive when something like `bitflags != 0` is used
Now `declare_interior_mutable_const` and `borrow_interior_mutable_const` respect the `ignore-interior-mutability` configuration entry
Fix#10537
changelog: Now `declare_interior_mutable_const` and `borrow_interior_mutable_const` respect the `ignore-interior-mutability` configuration entry
[`map_identity`]: allow closure with type annotations
Fixes#9122
`.map(|a: u32| a)` can help type inference, so we should probably allow this and not warn about "unnecessary map of the identity function"
changelog: [`map_identity`]: allow closure with type annotations
Implement rustc part of RFC 3127 trim-paths
This PR implements (or at least tries to) [RFC 3127 trim-paths](https://github.com/rust-lang/rust/issues/111540), the rustc part. That is `-Zremap-path-scope` with all of it's components/scopes.
`@rustbot` label: +F-trim-paths
Deserialize `Msrv` directly in `Conf`
Gives the error a span pointing to the invalid config value
Also puts `Conf` itself in the `OnceLock` rather than just the `Msrv` for [the `register_late_mod_pass` work](https://github.com/rust-lang/rust/pull/116731) since it will be used from two different callbacks
changelog: none
add lint for struct field names
changelog: [`struct_field_names`]: lint structs with the same pre/postfix in all fields or with fields that are pre/postfixed with the name of the struct.
fixes#2555
I've followed general structure and naming from the code in [enum_variants](b788addfcc/clippy_lints/src/enum_variants.rs) lint, which implements the same logic for enum variants.
side effect for `enum_variants`:
use .first() instead of .get(0) in enum_variants lint
move to_camel_case to str_util module
move module, enum and struct name repetitions check to a single file `item_name_repetitions`
rename enum_variants threshold config option
Make `multiple_unsafe_ops_per_block` ignore await desugaring
The await desugaring contains two calls (`Poll::new_unchecked` and `get_context`) inside a single unsafe block. That violates the lint.
fixes#11312
changelog: [`multiple_unsafe_ops_per_block`]: fix false positives in `.await`
[`unnecessary_lazy_eval`]: reduce applicability if closure has return type annotation
Fixes#11672
We already check if closure parameters don't have type annotations and reduce the applicability to `MaybeIncorrect` if they do, since those help type inference and removing them breaks code. We didn't do this for return type annotations however. This PR adds it. This doesn't change it to produce a fix that will compile, but it will prevent rustfix from auto-applying it.
(In general I'm not sure if we can suggest a fix that will compile. In this specific example, it might be possible to suggest `&[] as &[u8]`, but as-casts won't always work, e.g. `Default::default() as &[u8]` is a compile error, so just reducing applicability should be a safe fix in any case for now)
changelog: [`unnecessary_lazy_eval`]: reduce applicability to `MaybeIncorrect` if closure has return type annotation
changelog: Now `declare_interior_mutable_const` and `borrow_interior_mutable_const` respect the `ignore-interior-mutability` configuration entry
Signed-off-by: slinkydeveloper <francescoguard@gmail.com>
[`get_first`]: lint on non-primitive slices
Fixes#11594
I left the issue open for a couple days before making the PR to see if anyone has something to say, but it looks like there aren't any objections to removing this check that prevented linting on non-primitive slices, so here's the PR now.
There's a couple of instances in clippy itself where we now emit the lint. The actual relevant change is in the first commit and fixing the `.get(0)` instances in clippy itself is in the 2nd commit.
changelog: [`get_first`]: lint on non-primitive slices
Fix/11134
Fix#11134
Hir of `qpath` will be `TypeRelative(Ty { kind: Path(LangItem...` when a closure contains macro (e.g. https://github.com/rust-lang/rust-clippy/issues/11651) and #11134, it causes panic.
This PR avoids panicking and emitting incomplete path string when `qpath` contains `LangItem`.
changelog: none
There are several that are unused and can be removed.
And there are some calls to `to_string`, which can be expressed more
nicely as a `foo_to_string` call, and then `to_string` need not be
`pub`. (This requires adding `pat_to_string`).
`impl_trait_in_params` now supports impls and traits
Before this PR, the lint `impl_trait_in_params`. This PR gives the lint support for functions in impls and traits. (Also, some pretty heavy refactor)
fixes#11548
changelog:[`impl_trait_in_params`] now supports `impl` blocks and functions in traits
Improve `redundant_locals` help message
Fixes#11625
AFAIK, `span_lint_and_help` points the beginning of spans when we pass multiple spans to the second argument, so This PR I also modified its help span and its message.
lint result of the given example in the issue will be:
```console
error: redundant redefinition of a binding `apple`
--> src/main.rs:5:5
|
5 | let apple = apple;
| ^^^^^^^^^^^^^^^^^^
|
help: `apple` is initially defined here
--> src/main.rs:4:9
|
4 | let apple = 42;
| ^^^^^
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_locals
```
I hope that this change might help reduce user confusion, but I'd appreciate alternative suggestions:)
changelog: [`redundant_locals`]: Now points at the rebinding of the variable
Fix `items_after_test_module` for non root modules, add applicable suggestion
Fixes#11050Fixes#11153
changelog: [`items_after_test_module`]: Now suggests a machine-applicable suggestion.
changelog: [`items:after_test_module`]: Also lints for non root modules
The word "active" is currently used in two different and confusing ways:
- `ACTIVE_FEATURES` actually means "available unstable features"
- `Features::active_features` actually means "features declared in the
crate's code", which can include feature within `ACTIVE_FEATURES` but
also others.
(This is also distinct from "enabled" features which includes declared
features but also some edition-specific features automatically enabled
depending on the edition in use.)
This commit changes the `Features::active_features` to
`Features::declared_features` which actually matches its meaning.
Likewise, `Features::active` becomes `Features::declared`.
std_instead_of_core: avoid lint inside of proc-macro
- fixes https://github.com/rust-lang/rust-clippy/issues/10198
note: The lint for the reported `thiserror::Error` has been suppressed by [Don't lint unstable moves in std_instead_of_core](https://github.com/rust-lang/rust-clippy/pull/9545/files#diff-2cb8a24429cf9d9898de901450d640115503a10454d692dddc6a073a299fbb7eR29) because `thiserror::Error` internally implements `std::error::Error for (derived struct)`.
changelog: [`std_intead_of_core`]: avoid linting inside proc-macro
I confirmed this change fixes the problem:
<details>
<summary>test result without the change</summary>
```console
error: used import from `std` instead of `core`
--> tests/ui/std_instead_of_core.rs:65:14
|
LL | #[derive(ImplStructWithStdDisplay)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the derive macro `ImplStructWithStdDisplay` (in Nightly builds, run with -Z macro-backtrace for more info)
```
</details>
Move `needless_pass_by_ref_mut`: `suspicious` -> `nursery`
[Related to [this Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/257328-clippy/topic/needless_pass_by_ref_mut.20isn't.20ready.20for.20stable)]
`needless_pass_by_ref_mut` has been released with some important bugs (notably having a lot of reported false positives and an ICE). So it may not be really ready for being in stable until these problems are solved. This PR changes the lint's category from `suspicious` to `nursery`, just that.
changelog: none
Partially outline code inside the panic! macro
This outlines code inside the panic! macro in some cases. This is split out from https://github.com/rust-lang/rust/pull/115562 to exclude changes to rustc.
There are cases where users create a unit variant for the purposes
of tracking the number of variants for an nonexhaustive enum.
We should check if an enum is explicitly marked as nonexhaustive
before reporting `manual_non_exhaustive` in these cases. Fixes#11583
new lint: `into_iter_without_iter`
Closes#9736 (part 2)
This implements the other lint that my earlier PR missed: given an `IntoIterator for &Type` impl, check that there exists an inherent `fn iter(&self)` method.
changelog: new lint: `into_iter_without_iter`
r? `@Jarcho` since you reviewed #11527 I figured it makes sense for you to review this as well?
[`manual_let_else`]: only omit block if span is from same ctxt
Fixes#11579.
The lint already had logic for omitting a block in `else` if a block is already present, however this didn't handle the case where the block is from a different expansion/syntax context. E.g.
```rs
macro_rules! panic_in_block {
() => { { panic!() } }
}
let _ = match Some(1) {
Some(v) => v,
_ => panic_in_block!()
};
```
It would see this in its expanded form as `_ => { panic!() }` and think it doesn't have to include a block in its suggestion because it is already there, however that's not true if it's from a different expansion like in this case.
changelog: [`manual_let_else`]: only omit block in suggestion if the block is from the same expansion
Clippy backport: Move needless_raw_string_hashes to pedantic
Really small backport this time. Context: https://github.com/rust-lang/rust-clippy/pull/11415#issuecomment-1739880932
I'd rather get this in 1.74 than waiting another release cycle.
r? `@Manishearth`
cc `@Mark-Simulacrum` This should be merged before beta is branched tomorrow.
mir_to_const improvements
This simplifies some code and also fixes the float array handling to properly take into account the `offset`, and to work with little-endian targets.
Fixes https://github.com/rust-lang/rust-clippy/issues/11488
changelog: none
Don't store lazyness in `DefKind::TyAlias`
1. Don't store lazyness of a type alias in its `DefKind`, but instead via a query.
2. This allows us to treat type aliases as lazy if `#[feature(lazy_type_alias)]` *OR* if the alias contains a TAIT, rather than having checks for both in separate parts of the codebase.
r? `@oli-obk` cc `@fmease`
subst -> instantiate
continues #110793, there are still quite a few uses of `subst` and `substitute`, but changing them all in the same PR was a bit too much, so I've stopped here for now.
prevent ice when threshold is 0 and enum has no variants
changelog: [`enum_variant_names`]: prevent ice when threshold is 0 and enum has no variants
r? `@y21`
Fixes the same ice issue raised during review of https://github.com/rust-lang/rust-clippy/pull/11496
Fix large_futures example
The value used in the large_futures example was not large enough to trigger the lint given the default threshold. The example also contained more code than necessary. This PR changes the value size from 1kB to 16kB and reduces the example in size.
changelog: [`large_futures`]: Fix and simplify example
fixed fp caused by moving &mut reference inside of a closure
changelog: [`needless_pass_by_ref mut`]: fixes false positive caused by not covering mutable references passed to a closure inside of a fuction
fixes#11545
The value used in the large_futures example was not large enough to
trigger the lint given the default threshold.
The example also contained more code than necessary.
This PR changes the value size from 1kB to 16kB and reduces the example
in size.
Remove most usage of `hir_ty_to_ty`
Removes the usages where there's a suitable query or the type was already available elsewhere. The remaining cases would all require more involved changes
changelog: none
r? `@Jarcho`
fix FP with needless_raw_string_hashes
changelog: Fix [`needless_raw_string_hashes`]: Continue the lint checking of raw string when `needless_raw_strings` is allowed.
fix#11420
rename mir::Constant -> mir::ConstOperand, mir::ConstKind -> mir::Const
Also, be more consistent with the `to/eval_bits` methods... we had some that take a type and some that take a size, and then sometimes the one that takes a type is called `bits_for_ty`.
Turns out that `ty::Const`/`mir::ConstKind` carry their type with them, so we don't need to even pass the type to those `eval_bits` functions at all.
However this is not properly consistent yet: in `ty` we have most of the methods on `ty::Const`, but in `mir` we have them on `mir::ConstKind`. And indeed those two types are the ones that correspond to each other. So `mir::ConstantKind` should actually be renamed to `mir::Const`. But what to do with `mir::Constant`? It carries around a span, that's really more like a constant operand that appears as a MIR operand... it's more suited for `syntax.rs` than `consts.rs`, but the bigger question is, which name should it get if we want to align the `mir` and `ty` types? `ConstOperand`? `ConstOp`? `Literal`? It's not a literal but it has a field called `literal` so it would at least be consistently wrong-ish...
``@oli-obk`` any ideas?
[`redundant_guards`]: lint if the pattern is on the left side
A tiny improvement to the `redundant_guards` lint. There's no associated issue for this, just noticed it while going through the code.
Right now it warns on `Some(x) if x == 2` and suggests `Some(2)`, but it didn't do that for `Some(x) if 2 == x` (i.e. when the local is on the right side and the pattern on the left side).
changelog: [`redundant_guards`]: also lint if the pattern is on the left side
Change defaults of `accept-comment-above-statement` and `accept-comment-above-attributes`
This patch sets the two configuration options for `undocumented_unsafe_blocks` to `true` by default: these are `accept-comment-above-statement` and `accept-comment-above-attributes`. Having these values `false` by default prevents what many users would consider clean code, e.g. placing the `// SAFETY:` comment above a single-line functino call, rather than directly next to the argument.
This was originally discussed in https://github.com/rust-lang/rust-clippy/issues/11162
changelog: [`undocumented_unsafe_blocks`]: set
`accept-comment-above-statement` and `accept-comment-above-attributes` to `true` by default.
Fix mutaby used async function argument in closure for `needless_pass_by_ref_mut`
Fixes https://github.com/rust-lang/rust-clippy/issues/11380.
The problem was that it needed to go through closures as well in async functions to correctly find the mutable usage of async function arguments.
changelog: Correctly handle mutable usage of async function arguments in closures.
r? `@Centri3`
This patch sets the two configuration options for
`undocumented_unsafe_blocks` to `true` by default: these are
`accept-comment-above-statement` and `accept-comment-above-attributes`.
Having these values `false` by default prevents what many users would
consider clean code, e.g. placing the `// SAFETY:` comment above a
single-line functino call, rather than directly next to the argument.
changelog: [`undocumented_unsafe_blocks`]: set
`accept-comment-above-statement` and `accept-comment-above-attributes`
to `true` by default.
Add redundant_as_str lint
This lint checks for `as_str` on a `String` immediately followed by `as_bytes` or `is_empty` as those methods are available on `String` too. This could possibly also be extended to `&[u8]` in the future.
changelog: New lint [`redundant_as_str`] #11526
move required_consts check to general post-mono-check function
This factors some code that is common between the interpreter and the codegen backends into shared helper functions. Also as a side-effect the interpreter now uses the same `eval` functions as everyone else to get the evaluated MIR constants.
Also this is in preparation for another post-mono check that will be needed for (the current hackfix for) https://github.com/rust-lang/rust/issues/115709: ensuring that all locals are dynamically sized.
I didn't expect this to change diagnostics, but it's just cycle errors that change.
r? `@oli-obk`
This lint checks for `as_str` on a `String` immediately followed by `as_bytes` or `is_empty` as those methods are available on `String` too. This could possibly also be extended to `&[u8]` in the future.
Split `needless_borrow` into two lints
Splits off the case where the borrow is used as a generic argument to a function. I think the two cases are different enough to warrant a separate lint.
The tests for the new lint have been reordered to group related parts together. Two warning have been dropped, one looked like it was testing the generic argument form, but it ends up triggering the auto-deref variant. The second was just a redundant test that didn't do anything interesting.
An issue with cycle detection is also included. The old version was checking if a cycle was reachable from a block when it should have been checking if the block is part or a cycle.
As a side note, I'm liking the style of just jamming all the tests into separate scopes in main.
changelog: Split off `needless_borrows_for_generic_args` from `needless_borrow`
[`filter_map_bool_then`]: include multiple derefs from adjustments
In #11506 this lint was improved to suggest one deref if the bool is behind references (fixed the FP #11503), however it might need multiple dereferences if the bool is behind multiple layers of references or custom derefs. E.g. `&&&bool` needs `***b`.
changelog: [`filter_map_bool_then`]: suggest as many dereferences as there are needed to get to the bool
add extra `byref` checking for the guard's local
changelog: [`redundant_guards`]: Now checks if the variable is bound using `ref` before linting.
The lint should not be emitted, when the local variable is bind by-ref in the pattern.
fixes#11465
[`useless_conversion`]: don't lint if type parameter has unsatisfiable bounds for `.into_iter()` receiver
Fixes#11300.
Before this PR, clippy assumed that if it sees a `f(x.into_iter())` call and the type at that argument position is generic over any `IntoIterator`, then the `.into_iter()` call must be useless because `x` already implements `IntoIterator`, *however* this assumption is not right if the generic parameter has more than just the `IntoIterator` bound (because other traits can be implemented for the IntoIterator target type but not the IntoIterator implementor, as can be seen in the linked issue: `<[i32; 3] as IntoIterator>::IntoIter` satisfies `ExactSizeIterator`, but `[i32; 3]` does not).
So, this PR makes it check that the type parameter only has a single `IntoIterator` bound. It *might* be possible to check if the type of `x` in `f(x.into_iter())` satisfies all the bounds on the generic type parameter as defined on the function (which would allow removing the `.into_iter()` call even with multiple bounds), however I'm not sure how to do that, and the current fix should always work.
**Edit:** This PR has been changed to check if any of the bounds don't hold for the type of the `.into_iter()` receiver, so we can still lint in some cases.
changelog: [`useless_conversion`]: don't lint `.into_iter()` if type parameter has multiple bounds
fix filter_map_bool_then with a bool reference
changelog: [`filter_map_bool_then`]: Fix the incorrect autofix when the `bool` in question is a reference.
fix#11503
[`extra_unused_type_parameters`]: Fix edge case FP for parameters in where bounds
Generic parameters can end up being used on the left side of where-bounds if they are not directly bound but instead appear nested in some concrete generic type. Therefore, we should walk the left side of where bounds, but only if the bounded type is *not* a generic param, in which case we still need to ignore the bound.
Fixes#11302
changelog: [`extra_unused_type_parameters`]: Fix edge case false positive for parameters in where bounds
Ignore closures for some type lints
Fixes#11417
`hir_ty_to_ty` is used in a couple of the `!is_local` lints, which doesn't play nicely inside bodies
changelog: none
Improve invalid let expression handling
- Move all of the checks for valid let expression positions to parsing.
- Add a field to ExprKind::Let in AST/HIR to mark whether it's in a valid location.
- Suppress some later errors and MIR construction for invalid let expressions.
- Fix a (drop) scope issue that was also responsible for #104172.
Fixes#104172Fixes#104868
treat host effect params as erased in codegen
This fixes the changes brought to codegen tests when effect params are added to libcore, by not attempting to monomorphize functions that get the host param by being `const fn`.
r? `@oli-obk`
This fixes the changes brought to codegen tests when effect params are
added to libcore, by not attempting to monomorphize functions that get
the host param by being `const fn`.
[`len_without_is_empty`]: follow type alias to find inherent `is_empty` method
Fixes#11165
When we see an `impl B` and `B` is a type alias to some type `A`, then we need to follow the type alias to look for an `is_empty` method on the aliased type `A`. Before this PR, it'd get the inherent impls of `B`, which there aren't any and so it would warn that there isn't an `is_empty` method even if there was one.
Passing the type alias `DefId` to `TyCtxt::type_of` gives us the aliased `DefId` (or simply return the type itself if it wasn't a type alias) so we can just use that
changelog: [`len_without_is_empty`]: follow type alias to find inherent `is_empty` method
[`implied_bounds_in_impls`]: include (previously omitted) associated types in suggestion
Fixes#11435
It now includes associated types from the implied bound that were omitted in the second bound. Example:
```rs
fn f() -> impl Iterator<Item = u8> + ExactSizeIterator> {..}
```
Suggestion before this change:
```diff
- pub fn my_iter() -> impl Iterator<Item = u32> + ExactSizeIterator {
+ pub fn my_iter() -> impl ExactSizeIterator {
```
It didn't include `<Item = u32>` on `ExactSizeIterator`. Now, with this change, it does.
```diff
- pub fn my_iter() -> impl Iterator<Item = u32> + ExactSizeIterator {
+ pub fn my_iter() -> impl ExactSizeIterator<Item = u32> {
```
We also now extend the span to include not just possible `+` ahead of it, but also behind it (an example for this is in the linked issue as well).
**Note:** The overall diff is a bit noisy, because building up the suggestion involves quite a bit more logic now and I decided to extract that into its own function. For that reason, I split this PR up into two commits. The first commit contains the actual "logic" changes. Second commit just moves code around.
changelog: [`implied_bounds_in_impls`]: include (previously omitted) associated types in suggestion
changelog: [`implied_bounds_in_impls`]: include the `+` behind bound if it's the last bound
Rename incorrect_impls to non_canonical_impls, move them to warn by default
The wording/category of these feel too strong to me, I would expect most of the time it's linting the implementations aren't going to be *incorrect*, just unnecessary
changelog: rename `incorrect_clone_impl_on_copy_type` to [`non_canonical_clone_impl`]
changelog: rename `incorrect_partial_ord_impl_on_ord_type` to [`non_canonical_partial_ord_impl`]
changelog: Move [`non_canonical_clone_impl`], [`non_canonical_partial_ord_impl`] to suspicious
Preserve literals and range kinds in `manual_range_patterns`
Fixes#11461
Also enables linting when there are 3 or fewer alternatives if one of them is already a range pattern
changelog: none
[`slow_vector_initialization`]: use the source span of vec![] macro and fix another FP
Fixes#11408
<details>
<summary>Also fixes a FP when the vec initializer comes from a macro other than `vec![]`</summary>
```rs
macro_rules! x {
() => { vec![] }
}
fn f() {
let mut v = x!();
v.resize(10, 0);
}
```
This shouldn't warn. The `x!` macro might be doing other things, so just replacing `x!()` with `vec![0; 10]` is not always an option.
</details>
I added some test cases for macro expansions, however I don't think there's a way to write a test for that specific warning that appeared in the linked issue. As far as I understand, that happens when the rust-src rustup component isn't installed (so the stdlib source is unavailable) and the span points to the `vec![]` *expansion*, instead of the `vec![]` that the user wrote.
changelog: [`slow_vector_initialization`]: use the source span of `vec![]` macro
changelog: [`slow_vector_initialization`]: only warn on `vec![]` expansions and allow other macros
fix fp when [`undocumented_unsafe_blocks`] not able to detect comment on globally defined const/static variables
fixes: #11246
changelog: fix detection on global variables for [`undocumented_unsafe_blocks`]
skip `todo!()` in `never_loop`
As promised in #11450, here is an implementation which skips occurrences of the `todo!()` macro.
changelog: [`never_loop`]: skip loops containing `todo!()`
Don't pass extra generic arguments in `needless_borrow`
fixes#10253
Also switches to using `implements_trait` which does ICE when clippy's debug assertions are enabled.
changelog: None
[`implied_bounds_in_impls`]: don't ICE on default generic parameter and move to nursery
Fixes#11422
This fixes two ICEs ([1](https://github.com/rust-lang/rust-clippy/issues/11422#issue-1872351763), [2](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=2901e6febb479d3bd2a74f8a5b8a9305)), and moves it to nursery for now, because this lint needs some improvements in its suggestion (see #11435, for one such example).
changelog: Moved [`implied_bounds_in_impls`] to nursery (Now allow-by-default)
[#11437](https://github.com/rust-lang/rust-clippy/pull/11437)
changelog: [`implied_bounds_in_impls`]: don't ICE on default generic parameter in supertrait clause
r? `@xFrednet` (since you reviewed my PR that added this lint, I figured it might make sense to have you review this as well since you have seen this code before. If you don't want to review this, sorry! Feel free to reroll then)
--------
As for the ICE, it's pretty complicated and very confusing imo, so I'm going to try to explain the idea here (partly for myself, too, because I've confused myself several times writing- and fixing this):
<details>
<summary>Expand</summary>
The general idea behind the lint is that, if we have this function:
```rs
fn f() -> impl PartialEq<i32> + PartialOrd<i32> { 0 }
```
We want to lint the `PartialEq` bound because it's unnecessary. That exact bound is already specified in `PartialOrd<i32>`'s supertrait clause:
```rs
trait PartialOrd<Rhs>: PartialEq<Rhs> {}
// PartialOrd<i32>: PartialEq<i32>
```
The way it does this is in two steps:
- Go through all of the bounds in the `impl Trait` return type and collect each of the trait's supertrait bounds into a vec. We also store the generic arguments for later.
- `PartialEq` has no supertraits, nothing to add.
- `PartialOrd` is defined as `trait PartialOrd: PartialEq`, so add `PartialEq` to the list, as well as the generic argument(s) `<i32>`
Once we are done, we have these entries in the vec: `[(PartialEq, [i32])]`
- Go through all the bounds again, and looking for those bounds that have their trait `DefId` in the implied bounds vec.
- `PartialEq` is in that vec. However, that is not enough, because the trait is generic. If the user wrote `impl PartialEq<String> + PartialOrd<i32>`, then `PartialOrd` clearly doesn't imply `PartialEq`. Which means, we also need to check that the generic parameters match. This is why we also collected the generic arguments in `PartialOrd<i32>`. This process of checking generic arguments is pretty complicated and is also where the two ICEs happened.
The way it checks that the generic arguments match is by comparing the generic parameters in the super trait clause:
```rs
trait PartialOrd<Rhs>: PartialEq<Rhs> {}
// ^^^^^^^^^^^^^^
```
...this needs to match...
```rs
fn f() -> impl PartialEq<i32> + ...
// ^^^^^^^^^^^^^^
```
In the compiler, the `Rhs` generic parameter is its own type and we cannot just compare it to `i32`. We need to "substitute" it.
Internally, `Rhs` is represented as `Rhs#1` (the number next to # represents the type parameter index. They start at 0, but 0 is "reserved" for the implicit `Self` generic parameter).
How do we go from `Rhs#1` to `i32`? Well, we know that all the generic parameters had to be substituted in the `impl ... + PartialOrd<i32>` type. So we subtract 1 from the type parameter index, giving us 0 (`Self` is not specified in that list of arguments). We use that as the index into the generic argument list `<i32>`. That's `i32`. Now we know that the supertrait clause looks like `: PartialEq<i32>`.
Then, we can compare that to what the user actually wrote on the bound that we think is being implied: `impl PartialEq<i32> + ...`.
Now to the actual bug: this whole logic doesn't take into account *default* generic parameters. Actually, `PartialOrd` is defined like this:
```rs
trait PartialOrd<Rhs = Self>: PartialEq<Rhs> {}
```
If we now have a function like this:
```rs
fn f() -> impl PartialOrd + PartialEq {}
```
that logic breaks apart... We look at the supertrait predicate `: PartialEq<Rhs>` (`Rhs` is `Rhs#1`), then take the first argument in the generic argument list `PartialEq<..>` to resolve the `Rhs`, but at this point we crash because there *is no* generic argument.
The index 0 is out of bounds. If this happens (and we even get to linting here, which could only happen if it passes typeck), it must mean that that generic parameter has a default type that is not required to be specified.
This PR changes the logic such that if we have a type parameter index that is out of bounds, it looks at the definition of the trait and check that there exists a default type that we can use instead.
So, we see `<Rhs = Self>`, and use `Self` for substitution, and end up with this predicate: `: PartialEq<Self>`. No crash this time.
</details>
`never_loop` catches `loop { panic!() }`
* Depends on: #11447
This is an outgrowth of #11447 which I felt would best be done as a separate PR because it yields significant new results.
This uses typecheck results to determine divergence, meaning we can now detect cases like `loop { std::process::abort() }` or `loop { panic!() }`. A downside is that `loop { unimplemented!() }` is also being linted, which is arguably a false positive. I'm not really sure how to check this from HIR though, and it seems best to leave this epicycle for a later PR.
changelog: [`never_loop`]: Now lints on `loop { panic!() }` and similar constructs
Fix span when linting `explicit_auto_deref` immediately after `needless_borrow`
fixes#11366
changelog: `explicit_auto_deref`: Fix span when linting immediately after `needless_borrow`
Add config flag for reborrows in explicit_iter_loop
This PR adds a config flag for enforcing explicit into iter lint for reborrowed values. The config flag, `enforce_iter_loop_reborrow`, can be added to clippy.toml files to enable the linting behaviour. By default the reborrow lint is disabled.
fixes: #11074
changelog: [`explicit_iter_loop`]: add config flag `enforce_iter_loop_reborrow` to disable reborrow linting by default
new lint: `iter_out_of_bounds`
Closes#11345
The original idea in the linked issue seemed to be just about arrays afaict, but I extended this to catch some other iterator sources such as `iter::once` or `iter::empty`.
I'm not entirely sure if this name makes a lot of sense now that it's not just about arrays anymore (specifically, not sure if you can call `.take(1)` on an `iter::Empty` to be "out of bounds"?).
changelog: [`iter_out_of_bounds`]: new lint
[`unnecessary_unwrap`]: lint on `.as_ref().unwrap()`
Closes#11371
This turned out to be a little more code than I originally thought, because the lint also makes sure to not lint if the user tries to mutate the option:
```rs
if option.is_some() {
option = None;
option.unwrap(); // don't lint here
}
```
... which means that even if we taught this lint to recognize `.as_mut()`, it would *still* not lint because that would count as a mutation. So we need to allow `.as_mut()` calls but reject other kinds of mutations.
Unfortunately it doesn't look like this is possible with `is_potentially_mutated` (seeing what kind of mutation happened).
This replaces it with a custom little visitor that does basically what it did before, but also allows `.as_mut()`.
changelog: [`unnecessary_unwrap`]: lint on `.as_ref().unwrap()`
skip float_cmp check if lhs is a custom type
*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog: [`float_cmp`]: allow float eq comparison when lhs is a custom type that implements PartialEq<f32/f64>
If the lhs of a comparison is not float, it means there is a user implemented PartialEq, and the caller is invoking that custom version of `==`, instead of the default floating point equal comparison.
People may wrap f32 with a struct (say `MyF32`) and implement its PartialEq that will do the `is_close()` check, so that `MyF32` can be compared with either f32 or `MyF32`.
[`if_then_some_else_none`]: look into local initializers for early returns
Fixes#11394
As the PR title says, problem was that it only looked for early returns in semi statements. Local variables don't count as such, so it didn't count `let _v = x?;` (or even just `let _ = return;`) as a possible early return and didn't realize that it can't lint then.
Imo the `stmts_contains_early_return` function that was used before is redundant. `contains_return` could already do that if we just made the parameter a bit more generic, just like `for_each_expr`, which can already accept `&[Stmt]`
changelog: [`if_then_some_else_none`]: look into local initializers for early returns
This commit adds a config flag for enforcing explicit into iter lint
for reborrowed values. The config flag, enforce_iter_loop_reborrow, can be
added to clippy.toml files to enable the linting behaviour. By default
the lint is not enabled.
fix "derivable_impls: attributes are ignored"
*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog: [`derivable_impls`]: allow the lint when the trait-impl methods has any attribute.
Added new lint: `reserve_after_initialization`
Closes https://github.com/rust-lang/rust-clippy/issues/11330.
A new lint that informs the user about a more concise way to create a vector with a known capacity.
Example:
```rust
let mut v: Vec<usize> = vec![];
v.reserve(10);
```
Produces the following help:
```rust
|
2 | / let mut v: Vec<usize> = vec![];
3 | | v.reserve(10);
| |__________________^ help: consider using `Vec::with_capacity(space_hint)`: `let v: Vec<usize> = Vec::with_capacity(10);`
|
```
And can be rewritten as:
```rust
let v: Vec<usize> = Vec::with_capacity(10);
```
changelog: new lint [`reserve_after_initialization`]
key idea:
for `f` in `.map(f)` and `.for_each(f)`:
1. `f` must be a closure with one parameter
2. don't lint if mutable paramter in clsure `f`: `|mut x| ...`
3. don't lint if parameter is moved
[new_without_default]: include `where` clause in suggestions, make applicable
changelog: [`new_without_default`]: include `where` clause in suggestions
Correctly handle async blocks for NEEDLESS_PASS_BY_REF_MUT
Fixes https://github.com/rust-lang/rust-clippy/issues/11299.
The problem was that the `async block`s are popping a closure which we didn't go into, making it miss the mutable access to the variables.
cc `@Centri3`
changelog: none
[`useless_conversion`]: only lint on paths to fn items and fix FP in macro
Fixes#11065 (which is actually two issues: an ICE and a false positive)
It now makes sure that the function call path points to a function-like item (and not e.g. a `const` like in the linked issue), so that calling `TyCtxt::fn_sig` later in the lint does not ICE (fixes https://github.com/rust-lang/rust-clippy/issues/11065#issuecomment-1616836099).
It *also* makes sure that the expression is not part of a macro call (fixes https://github.com/rust-lang/rust-clippy/issues/11065#issuecomment-1616919639). ~~I'm not sure if there's a better way to check this other than to walk the parent expr chain and see if any of them are expansions.~~ (edit: it doesn't do this anymore)
changelog: [`useless_conversion`]: fix ICE when call receiver is a non-fn item
changelog: [`useless_conversion`]: don't lint if argument is a macro argument (fixes a FP)
r? `@llogiq` (reviewed #10814, which introduced these issues)
Correctly handle async blocks for NEEDLESS_PASS_BY_REF_MUT
Fixes https://github.com/rust-lang/rust-clippy/issues/11299.
The problem was that the `async block`s are popping a closure which we didn't go into, making it miss the mutable access to the variables.
cc `@Centri3`
changelog: none
[`useless_conversion`]: only lint on paths to fn items and fix FP in macro
Fixes#11065 (which is actually two issues: an ICE and a false positive)
It now makes sure that the function call path points to a function-like item (and not e.g. a `const` like in the linked issue), so that calling `TyCtxt::fn_sig` later in the lint does not ICE (fixes https://github.com/rust-lang/rust-clippy/issues/11065#issuecomment-1616836099).
It *also* makes sure that the expression is not part of a macro call (fixes https://github.com/rust-lang/rust-clippy/issues/11065#issuecomment-1616919639). ~~I'm not sure if there's a better way to check this other than to walk the parent expr chain and see if any of them are expansions.~~ (edit: it doesn't do this anymore)
changelog: [`useless_conversion`]: fix ICE when call receiver is a non-fn item
changelog: [`useless_conversion`]: don't lint if argument is a macro argument (fixes a FP)
r? `@llogiq` (reviewed #10814, which introduced these issues)
redundant_locals: fix FPs on mutated shadows
Fixes#11290.
When a mutable binding is shadowed by
a mutable binding of the same name in a different scope, mutations in that scope have different meaning.
This PR fixes spurious `redundant_locals` emissions on such locals.
cc `@Centri3,` `@flip1995`
changelog: [`redundant_locals`]: fix false positives on mutated shadows
Rustup
r? `@ghost`
cc `@max-niederman` With the latest sync, I'm getting a lot of FP in the `redundant_locals` lint you recently added. Any ideas where this could come from?
changelog: none
When a mutable binding is shadowed by
a mutable binding of the same name in a different scope,
mutations in that scope have different meaning.
This commit fixes spurious `redundant_locals` emissions
on such locals.
[`filter_map_bool_then`]: Don't ICE on late bound regions
Fixes#11309
Also lints `&NonCopy` now, since any `&` is `Copy`. That was accidental, but it seems that this is a consequence (or improvement!) of this fix.
r? `@Jarcho`
changelog: [`filter_map_bool_then`]: Don't ICE on late bound regions
[`redundant_guards`]: don't lint on float literals
Fixes#11304
changelog: [`redundant_guards`]: don't lint on float literals
r? `@Centri3` i figured you are probably a good reviewer for this since you implemented the lint ^^
Store the laziness of type aliases in their `DefKind`
Previously, we would treat paths referring to type aliases as *lazy* type aliases if the current crate had lazy type aliases enabled independently of whether the crate which the alias was defined in had the feature enabled or not.
With this PR, the laziness of a type alias depends on the crate it is defined in. This generally makes more sense to me especially if / once lazy type aliases become the default in a new edition and we need to think about *edition interoperability*:
Consider the hypothetical case where the dependency crate has an older edition (and thus eager type aliases), it exports a type alias with bounds & a where-clause (which are void but technically valid), the dependent crate has the latest edition (and thus lazy type aliases) and it uses that type alias. Arguably, the bounds should *not* be checked since at any time, the dependency crate should be allowed to change the bounds at will with a *non*-major version bump & without negatively affecting downstream crates.
As for the reverse case (dependency: lazy type aliases, dependent: eager type aliases), I guess it rules out anything from slight confusion to mild annoyance from upstream crate authors that would be caused by the compiler ignoring the bounds of their type aliases in downstream crates with older editions.
---
This fixes#114468 since before, my assumption that the type alias associated with a given weak projection was lazy (and therefore had its variances computed) did not necessarily hold in cross-crate scenarios (which [I kinda had a hunch about](https://github.com/rust-lang/rust/pull/114253#discussion_r1278608099)) as outlined above. Now it does hold.
`@rustbot` label F-lazy_type_alias
r? `@oli-obk`
redundant_type_annotations: only pass certain def kinds to type_of
Fixes#11190Fixesrust-lang/rust#113516
Also adds an `is_lint_allowed` check to skip the lint when it's not needed
changelog: none
Add documentation to has_deref
Documentation of `has_deref` needed some polish to be more clear about where it should be used and what's it's purpose.
cc https://github.com/rust-lang/rust/issues/114401
r? `@RalfJung`
Improve spans for indexing expressions
fixes#114388
Indexing is similar to method calls in having an arbitrary left-hand-side and then something on the right, which is the main part of the expression. Method calls already have a span for that right part, but indexing does not. This means that long method chains that use indexing have really bad spans, especially when the indexing panics and that span in coverted into a panic location.
This does the same thing as method calls for the AST and HIR, storing an extra span which is then put into the `fn_span` field in THIR.
r? compiler-errors
Lots of tiny incremental simplifications of `EmitterWriter` internals
ignore the first commit, it's https://github.com/rust-lang/rust/pull/114088 squashed and rebased, but it's needed to use to use `derive_setters`, as they need a newer `syn` version.
Then this PR starts out with removing many arguments that are almost always defaulted to `None` or `false` and replace them with builder methods that can set these fields in the few cases that want to set them.
After that it's one commit after the other that removes or merges things until everything becomes some very simple trait objects
Indexing is similar to method calls in having an arbitrary
left-hand-side and then something on the right, which is the main part
of the expression. Method calls already have a span for that right part,
but indexing does not. This means that long method chains that use
indexing have really bad spans, especially when the indexing panics and
that span in coverted into a panic location.
This does the same thing as method calls for the AST and HIR, storing an
extra span which is then put into the `fn_span` field in THIR.
Fix `suspicious_xor_used_as_pow.rs` performance
The original `suspicious_xor_used_as_pow` lint had poor performance, so I fixed that + a little refactor so that module is readable.
**107 millis. -> 106 millis.** Using `SPEEDTEST` on Rust's VMs
fix#11060
changelog: [`suspicious_xor_used_as_pow`]: Improve performance by 0.934%
Expand, rename and improve `incorrect_fn_null_checks` lint
This PR,
- firstly, expand the lint by now linting on references
- secondly, it renames the lint `incorrect_fn_null_checks` -> `useless_ptr_null_checks`
- and thirdly it improves the lint by catching `ptr::from_mut`, `ptr::from_ref`, as well as `<*mut _>::cast` and `<*const _>::cast_mut`
Fixes https://github.com/rust-lang/rust/issues/113601
cc ```@est31```
New lint `ignored_unit_patterns`
This idea comes from #11238. I've put the lint in `pedantic` as it might trigger numerous positives (three in Clippy itself).
changelog: [`ignored_unit_patterns`]: new lint
Suppress `question_mark` warning if `question_mark_used` is not allowed
Closes#11283
changelog: [`question_mark`]: Don't lint if `question_mark_used` is not allowed