Commit graph

10104 commits

Author SHA1 Message Date
Michael Krasnitski
f598bb75d4 Walk the left side of where bounds if the bounded type is not a generic parameter 2023-09-11 21:43:27 -04:00
Samuel Tardieu
c548d11041 Auto deref does not apply on union field 2023-09-10 18:15:18 +02:00
bors
8c48b936cc Auto merge of #11459 - y21:issue11435, r=blyxyas
[`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
2023-09-09 22:51:42 +00:00
bors
ec6f1bd4bf Auto merge of #11358 - Alexendoo:incorrect-to-manual-impls, r=Jarcho
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
2023-09-09 11:44:51 +00:00
bors
27165acadf Auto merge of #11456 - tom-anders:std_instead_of_core_suggestion, r=Manishearth
Add suggestions for std_instead_of_core

```
changelog: [`std_instead_of_core`]: add suggestions
```

Fixes #11446
2023-09-08 15:59:00 +00:00
Alex Macleod
b99921a5e8 Rename incorrect_impls to non_canonical_impls, move them to warn by default 2023-09-08 13:15:51 +00:00
Philipp Krones
d2b08432db
Merge remote-tracking branch 'upstream/master' into rustup 2023-09-07 21:43:06 +02:00
bors
6150bf5b92 Auto merge of #11462 - Alexendoo:manual-range-patterns-preserve-literals, r=blyxyas
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
2023-09-07 13:50:16 +00:00
bors
415ba21c3b Auto merge of #11451 - y21:issue11408, r=xFrednet
[`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
2023-09-07 11:03:01 +00:00
bors
0d36d57c41 Auto merge of #11439 - Alexendoo:disallowed-macros-bins-attrs, r=xFrednet
Check binary operators and attributes in disallowed_macros

changelog: none
2023-09-06 11:36:28 +00:00
y21
30846b16a0 add comments in code to clarify and fix typo 2023-09-05 21:55:08 +02:00
Alex Macleod
bbf67c3424 Preserve literals and range kinds in manual_range_patterns 2023-09-05 13:20:37 +00:00
bors
eb0df1d4f4 Auto merge of #11454 - samueltardieu:issue-11403, r=Centri3
Ignore wildcards in function arguments and local bindings

Fix #11403

changelog: none
2023-09-05 12:01:31 +00:00
Samuel Tardieu
2f5c445c0b Ignore wildcards in function arguments and local bindings 2023-09-04 17:18:33 +02:00
bors
bcf856bfb3 Auto merge of #11375 - J-ZhengLi:issue11246, r=Centri3
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`]
2023-09-04 09:47:45 +00:00
bors
da882f0a5a Auto merge of #11455 - digama0:never_loop3, r=Centri3,dswij
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!()`
2023-09-04 05:51:47 +00:00
Mario Carneiro
4e0a3465d1 fix vec.rs test, comment 2023-09-04 06:35:51 +02:00
bors
f13e1f429a Auto merge of #11259 - Jarcho:ice_10253, r=dswij
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
2023-09-04 03:17:50 +00:00
y21
32e25118a6 extract lint emitting into separate fn 2023-09-03 22:53:37 +02:00
y21
7262145964 [implied_bounds_in_impl]: fix suggestion for assoc types 2023-09-03 22:21:03 +02:00
bors
3de0f19c41 Auto merge of #11437 - y21:issue-11422, r=xFrednet
[`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>
2023-09-03 16:09:40 +00:00
Mario Carneiro
1317378b9e fix todo item check, remove unimplemented 2023-09-03 17:16:06 +02:00
Camille GILLOT
d5f0f443b9 Fix clippy. 2023-09-03 15:02:47 +00:00
Camille GILLOT
c3170771f3 Use relative positions inside a SourceFile. 2023-09-03 12:56:10 +00:00
tom-anders
e0014afa2d Add suggestions for std_instead_of_core
Fixes #11446
2023-09-03 14:34:40 +02:00
Mario Carneiro
61a2f972b3 skip todo / unimplemented in never_loop 2023-09-03 01:54:28 -04:00
y21
51206323a1 [slow_vector_initialization]: only warn on vec![] expn 2023-09-02 16:31:17 +02:00
y21
78983d9e3f [slow_vector_initialization]: use the source span of vec![] macro 2023-09-02 15:46:15 +02:00
bors
b9906aca5a Auto merge of #11450 - digama0:never_loop2, r=llogiq
`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
2023-09-02 12:34:47 +00:00
Mario Carneiro
b3980d8497 catch never loops through diverging functions 2023-09-02 07:51:34 -04:00
Mario Carneiro
39b316db61 an empty match diverges 2023-09-02 07:32:38 -04:00
Ralf Jung
79e31cb80e DefaultUnionRepresentation: explain why we only warn about unions with at least 2 non-ZST fields 2023-09-02 11:36:34 +02:00
Mario Carneiro
68011893d8 Rewrite never_loop as a strict reachability pass
fixes #11004
2023-09-02 03:14:19 -04:00
bors
a8b5245ea3 Auto merge of #11416 - Alexendoo:raw-strings-multipart, r=xFrednet
Use multipart suggestions for raw string lints

Should make it slightly easier to see the suggested edit

Before/after for `needless_raw_string_hashes`:

| Before| After |
|--------|--------|
| ![before](https://github.com/rust-lang/rust-clippy/assets/1830331/da52a436-d890-4594-9191-819c1af946c7) | ![after](https://github.com/rust-lang/rust-clippy/assets/1830331/9731d790-8efa-42a2-b2e9-0ec51398f8f3) |

changelog: none
2023-09-01 22:19:57 +00:00
Alex Macleod
f595f1e0ff Use multipart suggestions for raw string lints 2023-09-01 21:18:51 +00:00
Caio
b3136a874d [clippy] Use symbols intended for arithmetic_side_effects 2023-09-01 10:28:55 +02:00
bors
c1f8ae3a4a Auto merge of #11430 - TDecking:vec-fmt, r=giraffate
Correctly format `vec!` invocations

The [Rust Style Guide](https://doc.rust-lang.org/nightly/style-guide/expressions.html?highlight=vec#array-literals) says that `vec!` should alwys be used with square brackets, not parenthesis. Within the lint documentation, that rule was violated twice.

changelog: none
2023-09-01 00:03:26 +00:00
y21
790922c5d6 update ui tests and some minor cleanups 2023-08-31 18:42:27 +02:00
y21
b54bac9f14 new lint: missing_assert_for_indexing 2023-08-31 17:44:19 +02:00
Alex Macleod
299fbceb96 Check binary operators and attributes in disallowed_macros 2023-08-31 13:14:44 +00:00
bors
77e395e87c Auto merge of #11376 - Jarcho:issue_11366, r=llogiq
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`
2023-08-31 11:30:37 +00:00
bors
c50d86fc6a Auto merge of #11418 - Benjscho:explicit_iter_loop_config, r=llogiq
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
2023-08-31 11:19:04 +00:00
y21
563abf9651 [implied_bounds_in_impls]: move to nursery and fix ICEs 2023-08-30 22:08:05 +02:00
bors
3da21b089f Auto merge of #11396 - y21:issue11345, r=Jarcho
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
2023-08-30 19:51:32 +00:00
Tobias Decking
1f8b204775
Second instance of vec! with parenthesis. 2023-08-30 14:02:44 +02:00
Tobias Decking
6eb7a46b88
Documentation Formatting 2023-08-30 13:36:37 +02:00
bors
b97eaab558 Auto merge of #11387 - y21:issue11371, r=blyxyas
[`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()`
2023-08-28 20:29:42 +00:00
bors
5cc5f27899 Auto merge of #11385 - markhuang1212:master, r=blyxyas
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`.
2023-08-28 18:27:53 +00:00
bors
4118738998 Auto merge of #11401 - y21:issue11394, r=xFrednet
[`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
2023-08-28 08:48:35 +00:00
Ben Schofield
be55a96d80 Add config flag for reborrows in explicit_iter_loop
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.
2023-08-27 21:45:14 -06:00