Commit graph

17202 commits

Author SHA1 Message Date
Niki4tap
0cd9b06125 Small code style adjustments 2022-12-23 00:56:50 +03:00
bors
4fe3727c39 Auto merge of #9701 - smoelius:improve-possible-borrower, r=Jarcho
Improve `possible_borrower`

This PR makes several improvements to `clippy_uitls::mir::possible_borrower`. These changes benefit both `needless_borrow` and `redundant clone`.

1. **Use the compiler's `MaybeStorageLive` analysis**

I could spot not functional differences between the one in the compiler and the one in Clippy's repository. So, I removed the latter in favor of the the former.

2. **Make `PossibleBorrower` a dataflow analysis instead of a visitor**

The main benefit of this change is that allows `possible_borrower` to take advantage of statements' relative locations, which is easier to do in an analysis than in a visitor.

This is easier to illustrate with an example, so consider this one:
```rust
    fn foo(cx: &LateContext<'_>, lint: &'static Lint) {
        cx.struct_span_lint(lint, rustc_span::Span::default(), "", |diag| diag.note(&String::new()));
        //                                                                          ^
    }
```
We would like to flag the `&` pointed to by the `^` for removal. `foo`'s MIR begins like this:
```rust
fn span_lint::foo::{closure#0}(_1: [closure@$DIR/needless_borrow.rs:396:68: 396:74], _2: &mut rustc_errors::diagnostic_builder::DiagnosticBuilder<'_, ()>) -> &mut rustc_errors::diagnostic_builder::DiagnosticBuilder<'_, ()> {
    debug diag => _2;                    // in scope 0 at $DIR/needless_borrow.rs:396:69: 396:73
    let mut _0: &mut rustc_errors::diagnostic_builder::DiagnosticBuilder<'_, ()>; // return place in scope 0 at $DIR/needless_borrow.rs:396:75: 396:75
    let mut _3: &mut rustc_errors::diagnostic_builder::DiagnosticBuilder<'_, ()>; // in scope 0 at $DIR/needless_borrow.rs:396:75: 396:100
    let mut _4: &mut rustc_errors::diagnostic_builder::DiagnosticBuilder<'_, ()>; // in scope 0 at $DIR/needless_borrow.rs:396:75: 396:100
    let mut _5: &std::string::String;    // in scope 0 at $DIR/needless_borrow.rs:396:85: 396:99
    let _6: std::string::String;         // in scope 0 at $DIR/needless_borrow.rs:396:86: 396:99

    bb0: {
        StorageLive(_3);                 // scope 0 at $DIR/needless_borrow.rs:396:75: 396:100
        StorageLive(_4);                 // scope 0 at $DIR/needless_borrow.rs:396:75: 396:100
        _4 = &mut (*_2);                 // scope 0 at $DIR/needless_borrow.rs:396:75: 396:100
        StorageLive(_5);                 // scope 0 at $DIR/needless_borrow.rs:396:85: 396:99
        StorageLive(_6);                 // scope 0 at $DIR/needless_borrow.rs:396:86: 396:99
        _6 = std::string::String::new() -> bb1; // scope 0 at $DIR/needless_borrow.rs:396:86: 396:99
                                         // mir::Constant
                                         // + span: $DIR/needless_borrow.rs:396:86: 396:97
                                         // + literal: Const { ty: fn() -> std::string::String {std::string::String::new}, val: Value(<ZST>) }
    }

    bb1: {
        _5 = &_6;                        // scope 0 at $DIR/needless_borrow.rs:396:85: 396:99
        _3 = rustc_errors::diagnostic_builder::DiagnosticBuilder::<'_, ()>::note::<&std::string::String>(move _4, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/needless_borrow.rs:396:75: 396:100
                                         // mir::Constant
                                         // + span: $DIR/needless_borrow.rs:396:80: 396:84
                                         // + literal: Const { ty: for<'a> fn(&'a mut rustc_errors::diagnostic_builder::DiagnosticBuilder<'_, ()>, &std::string::String) -> &'a mut rustc_errors::diagnostic_builder::DiagnosticBuilder<'_, ()> {rustc_errors::diagnostic_builder::DiagnosticBuilder::<'_, ()>::note::<&std::string::String>}, val: Value(<ZST>) }
    }
```
The call to `diag.note` appears in `bb1` on the line beginning with `_3 =`. The `String` is owned by `_6`. So, in the call to `diag.note`, we would like to know whether there are any references to `_6` besides `_5`.

The old, visitor approach did not consider the relative locations of statements. So all borrows were treated the same, *even if they occurred after the location of interest*.

For example, before the `_3 = ...` call, the possible borrowers of `_6` would be just `_5`. But after the call, the possible borrowers would include `_2`, `_3`, and `_4`.

So, in a sense, the call from which we are try to remove the needless borrow is trying to prevent us from removing the needless borrow(!).

With an analysis, things do not get so muddled. We can determine the set of possible borrowers at any specific location, e.g., using a `ResultsCursor`.

3. **Change `only_borrowers` to `at_most_borrowers`**

`possible_borrowers` exposed a function `only_borrowers` that determined whether the borrowers of some local were *exactly* some set `S`. But, from what I can tell, this was overkill. For the lints that currently use `possible_borrower` (`needless_borrow` and `redundant_clone`), all we really want to know is whether there are borrowers *other than* those in `S`. (Put another way, we only care about the subset relation in one direction.) The new function `at_most_borrowers` takes this more tailored approach.

4. **Compute relations "on the fly" rather than using `transitive_relation`**

The visitor would compute and store the transitive closure of the possible borrower relation for an entire MIR body.

But with an analysis, there is effectively a different possible borrower relation at each location in the body. Computing and storing a transitive closure at each location would not be practical.

So the new approach is to compute the transitive closure on the fly, as needed. But the new approach might actually be more efficient, as I now explain.

In all current uses of `at_most_borrowers` (previously `only_borrowers`), the size of the set of borrowers `S` is at most 2. So you need only check at most three borrowers to determine whether the subset relation holds. That is, once you have found a third borrower, you can stop, since you know the relation cannot hold.

Note that `transitive_relation` is still used by `clippy_uitls::mir::possible_origin` (a kind of "subroutine" of `possible_borrower`).

cc: `@Jarcho`

---

changelog: [`needless_borrow`], [`redundant_clone`]: Now track references better and detect more cases
[#9701](https://github.com/rust-lang/rust-clippy/pull/9701)
<!-- changelog_checked -->
2022-12-22 15:08:04 +00:00
bors
8a6e6fd623 Auto merge of #10056 - koka831:fix/9993, r=Jarcho
Avoid `match_wildcard_for_single_variants` on guarded wild matches

fix #9993

changelog: FP: [`match_wildcard_for_single_variants`]: No longer lints on wildcards with a guard
[#10056](https://github.com/rust-lang/rust-clippy/pull/10056)
<!-- changelog_checked -->

r? `@Jarcho`
2022-12-22 14:54:50 +00:00
bors
f0d331ab36 Auto merge of #10109 - Niki4tap:yeet_not_return, r=flip1995
Fix FP in needless_return when using yeet

Fixes #9947

changelog: Fix: [`needless_return`]: don't lint when using `do yeet`
#10109
2022-12-22 10:40:33 +00:00
Niki4tap
b6882f6107 Fix FP in needless_return when using yeet 2022-12-22 12:47:39 +03:00
bors
065c6f78e7 Auto merge of #10091 - EricWu2003:manual-filter-FP, r=llogiq
fix manual_filter false positive

fixes #10088
fixes #9766

changelog: FP: [`manual_filter`]: Now ignores if expressions where the else branch has side effects or doesn't return `None`
[#10091](https://github.com/rust-lang/rust-clippy/pull/10091)
<!-- changelog_checked -->
2022-12-21 19:39:32 +00:00
bors
4a09068f87 Auto merge of #10063 - chansuke:issue-9702, r=Alexendoo
add [`permissions_set_readonly_false`] #9702

Add slight modification on [this PR](https://github.com/rust-lang/rust-clippy/pull/9744).

---

changelog: New lint [`permissions_set_readonly_false`]
[#10063](https://github.com/rust-lang/rust-clippy/pull/10063)
<!-- changelog_checked -->
2022-12-20 16:03:11 +00:00
chansuke
b21cc36ee9 hotfix: add help dialog for PermissionExt 2022-12-20 23:43:34 +09:00
Samuel Moelius
4dbd8ad34e Address https://github.com/rust-lang/rust/pull/105659 2022-12-20 05:30:12 -05:00
Samuel Moelius
c7dc961558 Address review comments 2022-12-20 05:12:13 -05:00
Samuel Moelius
26df55112f Fix adjacent code 2022-12-20 05:12:13 -05:00
Samuel Moelius
ed519ad746 Improve possible_borrower 2022-12-20 05:12:13 -05:00
Samuel Moelius
c6477eb711 Add tests 2022-12-20 05:12:13 -05:00
Samuel Moelius
cd3d38aa27 Use rustc_mir_dataflow::impls::MaybeStorageLive 2022-12-20 05:12:13 -05:00
bors
1e68973582 Auto merge of #10067 - chansuke:issue-7943, r=giraffate
Add 2018/2021 edition tests for wildcard_imports

Fixes #7943

---

changelog: none
<!-- changelog_checked -->
2022-12-20 00:28:21 +00:00
Michael Goulet
24444945ec Make Clippy test no longer unsound 2022-12-19 18:16:22 +00:00
bors
09cfcaf693 Auto merge of #10103 - Niki4tap:overflow_ice, r=flip1995
Fix overflow ICE in large_stack/const_arrays

Change `maximum_allowed_size` config variable type from `u64` to `u128`, and converting total array sizes to `u128` to avoid overflow during multiplication.

Fixes #10044

changelog: Fix: [`large_const_arrays`] and [`large_stack_arrays`]: avoid integer overflow when calculating total array size
#10103
2022-12-19 16:43:32 +00:00
chansuke
e1d3c1e8f1 refactor: fix style 2022-12-20 00:37:53 +09:00
dboso
30e6e85508 add [permissions_set_readonly_false] #9702 2022-12-20 00:37:51 +09:00
Niki4tap
d0ac6ba0b1 Fix overflow ICE in large_stack/const_arrays 2022-12-19 18:27:42 +03:00
bors
b3145fea6a Auto merge of #10099 - Niki4tap:null_fn_lints, r=llogiq
Null fn lints

Adds lints to check for code, that assumes nullable `fn()`.

### Lint examples:

`transmute_null_to_fn`:
```rust
error: transmuting a known null pointer into a function pointer
  --> $DIR/transmute_null_to_fn.rs:9:23
   |
LL |         let _: fn() = std::mem::transmute(std::ptr::null::<()>());
   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior
   |
   = help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value
```

`fn_null_check`:
```rust
error: function pointer assumed to be nullable, even though it isn't
  --> $DIR/fn_null_check.rs:13:8
   |
LL |     if (fn_ptr as *mut ()).is_null() {}
   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: try wrapping your function pointer type in `Option<T>` instead, and using `is_none` to check for null pointer value
```

Closes #1644

---

changelog: Improvement: [`transmuting_null`]: Now detects `const` pointers to all types
[#10099](https://github.com/rust-lang/rust-clippy/pull/10099)
changelog: New lint: [`transmute_null_to_fn`]
[#10099](https://github.com/rust-lang/rust-clippy/pull/10099)
changelog: New lint: [`fn_null_check`]
[#10099](https://github.com/rust-lang/rust-clippy/pull/10099)
<!-- changelog_checked (This is just a flag for me, please don't add it manually) -->
2022-12-19 12:44:23 +00:00
Niki4tap
691df70bbc Inline some consts 2022-12-19 15:34:55 +03:00
bors
8a6aca35b5 Auto merge of #10101 - flip1995:manual_clamp_nursery, r=xFrednet
Move manual_clamp to nursery

As discussed in https://github.com/rust-lang/rust-clippy/pull/9484#issuecomment-1278922613 and decided in the [Zulip meeting](https://rust-lang.zulipchat.com/#narrow/stream/257328-clippy/topic/Meeting.202022-12-13/near/315626226)

changelog: Moved [`manual_clamp`] to `nursery` (Now allow-by-default)
[#10101](https://github.com/rust-lang/rust-clippy/pull/10101)
<!-- changelog_checked -->
2022-12-19 09:56:43 +00:00
Philipp Krones
62061b8a05
Move manual_clamp to nursery 2022-12-19 09:44:56 +01:00
Niki4tap
cc98574883 Fix comments, use constant instead of raw constant_context 2022-12-18 22:47:02 +03:00
Niki4tap
20f501a9d9 Improve code style further 2022-12-18 22:39:06 +03:00
Niki4tap
9b2fc8e2a2 Make clippy happy 2022-12-18 19:43:26 +03:00
bors
910a97d7ce Auto merge of #10020 - samueltardieu:more-into-iter-removal, r=xFrednet
Identify more cases of useless `into_iter()` calls

changelog: Sugg: [`useless_conversion`]: Now suggests removing calls to `into_iter()` on an expression implementing `Iterator`
[#10020](https://github.com/rust-lang/rust-clippy/pull/10020)
<!-- changelog_checked -->
2022-12-18 16:01:29 +00:00
Niki4tap
b1ca307168 Address some of the code style issues 2022-12-18 18:58:15 +03:00
koka
ebb0759bb3
Add a test for regular wildcard
fix
2022-12-18 21:07:18 +09:00
Niki4tap
dae54fad3e Doc codeblock fixup 2022-12-18 03:20:04 +03:00
Niki4tap
54a9168efb Remove useless pattern matching 2022-12-18 03:02:45 +03:00
Niki4tap
42106e0495 Add lint fn_null_check 2022-12-18 03:02:45 +03:00
Niki4tap
3cc67d0856 Relax clippy_utils::consts::miri_to_const pointer type restrictiveness 2022-12-18 03:02:45 +03:00
Niki4tap
6afe5471cf Add lint transmute_null_to_fn 2022-12-18 03:02:37 +03:00
Samuel Tardieu
af39a8a4a8 Identify more cases of useless into_iter() calls
If the type of the result of a call to `IntoIterator::into_iter()`
and the type of the receiver are the same, then the receiver
implements `Iterator` and `into_iter()` is the identity function.

The call to `into_iter()` may be removed in all but two cases:

- If the receiver implements `Copy`, `into_iter()` will produce
  a copy of the receiver and cannot be removed. For example,
  `x.into_iter().next()` will not advance `x` while `x.next()` will.
- If the receiver is an immutable local variable and the call to
  `into_iter()` appears in a larger expression, removing the call to
  `into_iter()` might cause mutability issues. For example, if `x`
  is an immutable local variable, `x.into_iter().next()` will
  compile while `x.next()` will not as `next()` receives
  `&mut self`.
2022-12-17 16:20:43 +01:00
Philipp Krones
1c422524c7 Merge commit '4bdfb0741dbcecd5279a2635c3280726db0604b5' into clippyup 2022-12-17 14:12:54 +01:00
bors
4bdfb0741d Auto merge of #10097 - flip1995:rustup, r=flip1995
Rustup

r? `@ghost`

I'm on the train and my internet is too bad to download the necessary toolchain, so I have to use CI to find sync fallout.

changelog: none
<!-- changelog_checked -->
2022-12-17 13:08:47 +00:00
Philipp Krones
7198989d45
Bump nightly version -> 2022-12-17 2022-12-17 13:57:48 +01:00
Philipp Krones
1f1d23cf51
Bump Clippy version -> 0.1.68 2022-12-17 13:57:41 +01:00
Philipp Krones
d6488ae144
Merge remote-tracking branch 'upstream/master' into rustup 2022-12-17 13:56:32 +01:00
bors
391b2a6fac Auto merge of #10096 - feniljain:fix-seek-rewind, r=xFrednet
fix: not suggest seek_to_start_instead_of_rewind when expr is used

changelog: [`seek_to_start_instead_of_rewind`]: No longer lints, if the return of `seek` is used.
[#10096](https://github.com/rust-lang/rust-clippy/pull/10096)
<!-- changelog_checked -->

Fixes #10065
2022-12-17 12:35:26 +00:00
feniljain
c39849a34d fix: not suggest seek_to_start_instead_of_rewind when expr is used 2022-12-17 17:31:34 +05:30
bors
b62319ce02 Auto merge of #10094 - EricWu2003:increment-visitor-fix, r=xFrednet
fix logic in IncrementVisitor

There used to be a logical bug where IncrementVisitor would completely stop checking an expression/block after seeing a continue statement.

I am a little unsure of whether my fix to `IncrementVisitor` is logically sound (I hope it makes sense). Let me know what you think, and thanks in advance for the review!

fixes #10058

---

changelog: FP: [`explicit_counter_loop`]: No longer ignores counter changes after `continue` expressions
[#10094](https://github.com/rust-lang/rust-clippy/pull/10094)
<!-- changelog_checked -->
2022-12-17 11:36:50 +00:00
chansuke
033f1ec797 Add 2018/2021 edition tests for wildcard_imports 2022-12-17 20:26:41 +09:00
Eric Wu
97c12e0460 fix logic in IncrementVisitor
There used to be a logical bug where IncrementVisitor would
completely stop checking an expression/block after seeing a continue
statement. This led to issue #10058 where a variable incremented
(or otherwise modified) after any continue statement would still be
considered incremented only once.

The solution is to continue scanning the expression after seeing a
`continue` statement, but increment self.depth so that the Visitor
thinks that the rest of the loop is within a conditional.
2022-12-16 10:54:12 -05:00
Eric Wu
3c14075b46 manual_filter: add a related test
The related issue is #9766 where the `manual_filter`
lint would remove side effects
2022-12-16 09:29:32 -05:00
Eric Wu
5b3a6669f7 fix manual_filter false positive
do explicit checks for the other branch being None
2022-12-15 23:53:28 -05:00
bors
02f3959f2b Auto merge of #10086 - nbdd0121:master, r=matthiaskrgr
Fix new_return_no_self with recursive bounds

Fix #10041

This uses a hash set, as described in https://github.com/rust-lang/rust-clippy/pull/10068#issuecomment-1352528391

changelog: [`new_return_no_self`]: fix stack overflow when the return type is `impl Trait` and contains recursive bounds
2022-12-16 02:08:39 +00:00
Matthias Krüger
cfe1e040e7 Rollup merge of #105743 - nnethercote:SimplifiedType-cleanups, r=lcnr
`SimplifiedType` cleanups

r? `@lcnr`
2022-12-15 22:03:01 +01:00