rust/tests/ui/moves
bors 6eaa7fb576 Auto merge of #122603 - estebank:clone-o-rama, r=lcnr
Detect borrow checker errors where `.clone()` would be an appropriate user action

When a value is moved twice, suggest cloning the earlier move:

```
error[E0509]: cannot move out of type `U2`, which implements the `Drop` trait
  --> $DIR/union-move.rs:49:18
   |
LL |         move_out(x.f1_nocopy);
   |                  ^^^^^^^^^^^
   |                  |
   |                  cannot move out of here
   |                  move occurs because `x.f1_nocopy` has type `ManuallyDrop<RefCell<i32>>`, which does not implement the `Copy` trait
   |
help: consider cloning the value if the performance cost is acceptable
   |
LL |         move_out(x.f1_nocopy.clone());
   |                             ++++++++
```

When a value is borrowed by an `fn` call, consider if cloning the result of the call would be reasonable, and suggest cloning that, instead of the argument:

```
error[E0505]: cannot move out of `a` because it is borrowed
  --> $DIR/variance-issue-20533.rs:53:14
   |
LL |         let a = AffineU32(1);
   |             - binding `a` declared here
LL |         let x = bat(&a);
   |                     -- borrow of `a` occurs here
LL |         drop(a);
   |              ^ move out of `a` occurs here
LL |         drop(x);
   |              - borrow later used here
   |
help: consider cloning the value if the performance cost is acceptable
   |
LL |         let x = bat(&a).clone();
   |                        ++++++++
```

otherwise, suggest cloning the argument:

```
error[E0505]: cannot move out of `a` because it is borrowed
  --> $DIR/variance-issue-20533.rs:59:14
   |
LL |         let a = ClonableAffineU32(1);
   |             - binding `a` declared here
LL |         let x = foo(&a);
   |                     -- borrow of `a` occurs here
LL |         drop(a);
   |              ^ move out of `a` occurs here
LL |         drop(x);
   |              - borrow later used here
   |
help: consider cloning the value if the performance cost is acceptable
   |
LL -         let x = foo(&a);
LL +         let x = foo(a.clone());
   |
```

This suggestion doesn't attempt to square out the types between what's cloned and what the `fn` expects, to allow the user to make a determination on whether to change the `fn` call or `fn` definition themselves.

Special case move errors caused by `FnOnce`:

```
error[E0382]: use of moved value: `blk`
  --> $DIR/once-cant-call-twice-on-heap.rs:8:5
   |
LL | fn foo<F:FnOnce()>(blk: F) {
   |                    --- move occurs because `blk` has type `F`, which does not implement the `Copy` trait
LL |     blk();
   |     ----- `blk` moved due to this call
LL |     blk();
   |     ^^^ value used here after move
   |
note: `FnOnce` closures can only be called once
  --> $DIR/once-cant-call-twice-on-heap.rs:6:10
   |
LL | fn foo<F:FnOnce()>(blk: F) {
   |          ^^^^^^^^ `F` is made to be an `FnOnce` closure here
LL |     blk();
   |     ----- this value implements `FnOnce`, which causes it to be moved when called
```

Account for redundant `.clone()` calls in resulting suggestions:

```
error[E0507]: cannot move out of dereference of `S`
  --> $DIR/needs-clone-through-deref.rs:15:18
   |
LL |         for _ in self.clone().into_iter() {}
   |                  ^^^^^^^^^^^^ ----------- value moved due to this method call
   |                  |
   |                  move occurs because value has type `Vec<usize>`, which does not implement the `Copy` trait
   |
note: `into_iter` takes ownership of the receiver `self`, which moves value
  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
help: you can `clone` the value and consume it, but this might not be your desired behavior
   |
LL |         for _ in <Vec<usize> as Clone>::clone(&self).into_iter() {}
   |                  ++++++++++++++++++++++++++++++    ~
```

We use the presence of `&mut` values in a move error as a proxy for the user caring about side effects, so we don't emit a clone suggestion in that case:

```
error[E0505]: cannot move out of `s` because it is borrowed
  --> $DIR/borrowck-overloaded-index-move-index.rs:53:7
   |
LL |     let mut s = "hello".to_string();
   |         ----- binding `s` declared here
LL |     let rs = &mut s;
   |              ------ borrow of `s` occurs here
...
LL |     f[s] = 10;
   |       ^ move out of `s` occurs here
...
LL |     use_mut(rs);
   |             -- borrow later used here
```

We properly account for `foo += foo;` errors where we *don't* suggest `foo.clone() += foo;`, instead suggesting `foo += foo.clone();`.

---

Each commit can be reviewed in isolation. There are some "cleanup" commits, but kept them separate in order to show *why* specific changes were being made, and their effect on tests' output.

Fix #49693, CC #64167.
2024-04-13 09:07:26 +00:00
..
assignment-of-clone-call-on-ref-due-to-missing-bound.fixed [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
assignment-of-clone-call-on-ref-due-to-missing-bound.rs [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
assignment-of-clone-call-on-ref-due-to-missing-bound.stderr recurse into refs when comparing tys for diagnostics 2023-12-07 23:00:46 -05:00
borrow-closures-instead-of-move.rs Point at continue and break that might be in the wrong place 2024-03-17 21:32:26 +00:00
borrow-closures-instead-of-move.stderr Point at continue and break that might be in the wrong place 2024-03-17 21:32:26 +00:00
issue-22536-copy-mustnt-zero.rs [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
issue-22536-copy-mustnt-zero.stderr Update tests 2024-02-07 10:42:01 +08:00
issue-34721.fixed [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
issue-34721.rs [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
issue-34721.stderr Show number in error message even for one error 2023-11-24 19:15:52 +01:00
issue-46099-move-in-macro.rs
issue-46099-move-in-macro.stderr Show number in error message even for one error 2023-11-24 19:15:52 +01:00
issue-72649-uninit-in-loop.rs Mention when the type of the moved value doesn't implement Clone 2024-04-11 16:41:42 +00:00
issue-72649-uninit-in-loop.stderr Auto merge of #122603 - estebank:clone-o-rama, r=lcnr 2024-04-13 09:07:26 +00:00
issue-75904-move-closure-loop.rs
issue-75904-move-closure-loop.stderr Better account for more cases involving closures 2024-04-12 04:46:31 +00:00
issue-99470-move-out-of-some.rs
issue-99470-move-out-of-some.stderr Show number in error message even for one error 2023-11-24 19:15:52 +01:00
move-1-unique.rs [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
move-2-unique.rs [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
move-2.rs [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
move-3-unique.rs [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
move-4-unique.rs [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
move-4.rs [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
move-arg-2-unique.rs [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
move-arg-2.rs [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
move-arg.rs [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
move-deref-coercion.rs
move-deref-coercion.stderr
move-fn-self-receiver.rs
move-fn-self-receiver.stderr Mention when the type of the moved value doesn't implement Clone 2024-04-11 16:41:42 +00:00
move-guard-same-consts.rs
move-guard-same-consts.stderr Show number in error message even for one error 2023-11-24 19:15:52 +01:00
move-in-guard-1.rs
move-in-guard-1.stderr Show number in error message even for one error 2023-11-24 19:15:52 +01:00
move-in-guard-2.rs
move-in-guard-2.stderr Show number in error message even for one error 2023-11-24 19:15:52 +01:00
move-into-dead-array-1.rs
move-into-dead-array-1.stderr Handle more cases of value suggestions 2024-04-10 20:36:14 +00:00
move-into-dead-array-2.rs
move-into-dead-array-2.stderr Show number in error message even for one error 2023-11-24 19:15:52 +01:00
move-nullary-fn.rs [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
move-of-addr-of-mut.rs
move-of-addr-of-mut.stderr Tweak value suggestions in borrowck and hir_analysis 2024-04-09 23:37:13 +00:00
move-out-of-array-1.rs
move-out-of-array-1.stderr Mention when the type of the moved value doesn't implement Clone 2024-04-11 16:41:42 +00:00
move-out-of-array-ref.rs
move-out-of-array-ref.stderr
move-out-of-field.rs [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
move-out-of-slice-1.rs
move-out-of-slice-1.stderr Show number in error message even for one error 2023-11-24 19:15:52 +01:00
move-out-of-slice-2.rs
move-out-of-slice-2.stderr
move-out-of-tuple-field.rs
move-out-of-tuple-field.stderr
move-scalar.rs [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
moves-based-on-type-access-to-field.rs
moves-based-on-type-access-to-field.stderr Show number in error message even for one error 2023-11-24 19:15:52 +01:00
moves-based-on-type-block-bad.rs
moves-based-on-type-block-bad.stderr Show number in error message even for one error 2023-11-24 19:15:52 +01:00
moves-based-on-type-capture-clause-bad.rs Better account for more cases involving closures 2024-04-12 04:46:31 +00:00
moves-based-on-type-capture-clause-bad.stderr Better account for more cases involving closures 2024-04-12 04:46:31 +00:00
moves-based-on-type-capture-clause.rs compiletest: Add a //@ needs-threads directive 2024-03-06 12:35:07 -08:00
moves-based-on-type-cyclic-types-issue-4821.rs
moves-based-on-type-cyclic-types-issue-4821.stderr Show number in error message even for one error 2023-11-24 19:15:52 +01:00
moves-based-on-type-distribute-copy-over-paren.rs
moves-based-on-type-distribute-copy-over-paren.stderr
moves-based-on-type-exprs.rs
moves-based-on-type-exprs.stderr
moves-based-on-type-match-bindings.rs
moves-based-on-type-match-bindings.stderr Show number in error message even for one error 2023-11-24 19:15:52 +01:00
moves-based-on-type-move-out-of-closure-env-issue-1965.rs
moves-based-on-type-move-out-of-closure-env-issue-1965.stderr Suggest .clone() in some move errors 2024-04-11 16:41:41 +00:00
moves-based-on-type-no-recursive-stack-closure.rs
moves-based-on-type-no-recursive-stack-closure.stderr
moves-based-on-type-tuple.rs
moves-based-on-type-tuple.stderr Show number in error message even for one error 2023-11-24 19:15:52 +01:00
moves-sru-moved-field.rs
moves-sru-moved-field.stderr Show number in error message even for one error 2023-11-24 19:15:52 +01:00
needs-clone-through-deref.fixed Silence redundant clone suggestion 2024-04-11 16:41:41 +00:00
needs-clone-through-deref.rs Silence redundant clone suggestion 2024-04-11 16:41:41 +00:00
needs-clone-through-deref.stderr Silence redundant clone suggestion 2024-04-11 16:41:41 +00:00
nested-loop-moved-value-wrong-continue.rs Point at continue and break that might be in the wrong place 2024-03-17 21:32:26 +00:00
nested-loop-moved-value-wrong-continue.stderr Point at continue and break that might be in the wrong place 2024-03-17 21:32:26 +00:00
pin-mut-reborrow-infer-var-issue-107419.fixed [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
pin-mut-reborrow-infer-var-issue-107419.rs [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
pin-mut-reborrow-infer-var-issue-107419.stderr Show number in error message even for one error 2023-11-24 19:15:52 +01:00
pin-mut-reborrow.fixed [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
pin-mut-reborrow.rs [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
pin-mut-reborrow.stderr Show number in error message even for one error 2023-11-24 19:15:52 +01:00
recreating-value-in-loop-condition.rs Add HELP to test 2024-03-17 21:45:03 +00:00
recreating-value-in-loop-condition.stderr Add HELP to test 2024-03-17 21:45:03 +00:00
suggest-clone-when-some-obligation-is-unmet.fixed Account for .clone() when suggesting <T as Clone>::clone 2024-04-11 16:41:40 +00:00
suggest-clone-when-some-obligation-is-unmet.rs [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
suggest-clone-when-some-obligation-is-unmet.stderr Account for .clone() when suggesting <T as Clone>::clone 2024-04-11 16:41:40 +00:00
suggest-clone.fixed Suggest .clone() in some move errors 2024-04-11 16:41:41 +00:00
suggest-clone.rs [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
suggest-clone.stderr Suggest .clone() in some move errors 2024-04-11 16:41:41 +00:00
use_of_moved_value_clone_suggestions.rs
use_of_moved_value_clone_suggestions.stderr Show number in error message even for one error 2023-11-24 19:15:52 +01:00
use_of_moved_value_copy_suggestions.fixed [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
use_of_moved_value_copy_suggestions.rs [AUTO-GENERATED] Migrate ui tests from // to //@ directives 2024-02-16 20:02:50 +00:00
use_of_moved_value_copy_suggestions.stderr