rust/compiler
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
..
rustc
rustc_abi
rustc_arena
rustc_ast Deduplicate is_comparison impl between BinOpKind and AssocOp 2024-04-11 07:36:34 +00:00
rustc_ast_ir introduce Mutability::ptr_str 2024-04-10 18:51:09 +02:00
rustc_ast_lowering Actually create ranged int types in the type system. 2024-04-08 12:02:19 +00:00
rustc_ast_passes Rollup merge of #123841 - Kohei316:remove_qualifier_sugg, r=wesleywiser 2024-04-12 17:41:35 +02:00
rustc_ast_pretty Add pattern types to ast 2024-04-08 11:54:22 +00:00
rustc_attr
rustc_baked_icu_data
rustc_borrowck Auto merge of #122603 - estebank:clone-o-rama, r=lcnr 2024-04-13 09:07:26 +00:00
rustc_builtin_macros Rollup merge of #123204 - notriddle:notriddle/include-str-span, r=pnkfelix 2024-04-12 17:41:32 +02:00
rustc_codegen_cranelift Merge commit '89f54caacf90e99fc8ba0d60a28bdadea3cfdf1e' into sync_cg_clif-2024-04-11 2024-04-11 10:42:48 +00:00
rustc_codegen_gcc Put PlaceValue into OperandValue::Ref, rather than 3 tuple fields 2024-04-11 00:10:10 -07:00
rustc_codegen_llvm Rollup merge of #123775 - scottmcm:place-val, r=cjgillot 2024-04-12 04:38:21 +02:00
rustc_codegen_ssa Auto merge of #121430 - madsmtm:mac-catalyst-iOSSupport, r=wesleywiser 2024-04-12 22:27:33 +00:00
rustc_const_eval Actually create ranged int types in the type system. 2024-04-08 12:02:19 +00:00
rustc_data_structures
rustc_driver
rustc_driver_impl Disable Ctrl-C handling on WASM 2024-04-11 12:35:47 +00:00
rustc_error_codes Update compiler/rustc_error_codes/src/error_codes/E0384.md 2024-04-12 22:43:38 +09:00
rustc_error_messages
rustc_errors Rollup merge of #123204 - notriddle:notriddle/include-str-span, r=pnkfelix 2024-04-12 17:41:32 +02:00
rustc_expand
rustc_feature remove some things that do not need to be 2024-04-11 21:09:52 +02:00
rustc_fluent_macro
rustc_fs_util
rustc_graphviz
rustc_hir Actually create ranged int types in the type system. 2024-04-08 12:02:19 +00:00
rustc_hir_analysis remove some things that do not need to be 2024-04-11 21:09:52 +02:00
rustc_hir_pretty Remove bin_op_to_assoc_op and invoke AssocOp::from_ast_binop directly 2024-04-11 07:36:34 +00:00
rustc_hir_typeck Rollup merge of #123834 - compiler-errors:async-closure-with-tainted-body, r=oli-obk 2024-04-12 21:46:58 +02:00
rustc_incremental
rustc_index
rustc_index_macros
rustc_infer Rollup merge of #123703 - estebank:diag-changes-2, r=Nadrieril 2024-04-11 01:56:26 +02:00
rustc_interface linker: Avoid some allocations in search directory iteration 2024-04-12 00:41:08 +03:00
rustc_lexer
rustc_lint Rollup merge of #123314 - surechen:fix_120642, r=Nadrieril 2024-04-11 01:56:24 +02:00
rustc_lint_defs Split back out unused_lifetimes -> redundant_lifetimes 2024-04-09 12:17:34 -04:00
rustc_llvm Rollup merge of #123612 - kxxt:riscv-target-abi, r=jieyouxu,nikic,DianQK 2024-04-10 04:27:40 +02:00
rustc_log
rustc_macros
rustc_metadata Rollup merge of #123827 - petrochenkov:searchdirs, r=Nadrieril 2024-04-12 04:38:23 +02:00
rustc_middle Rollup merge of #123834 - compiler-errors:async-closure-with-tainted-body, r=oli-obk 2024-04-12 21:46:58 +02:00
rustc_mir_build Suppress erroneous suggestion 2024-04-12 17:45:15 +01:00
rustc_mir_dataflow Actually create ranged int types in the type system. 2024-04-08 12:02:19 +00:00
rustc_mir_transform Use a helper to zip together parent and child captures for coroutine-closures 2024-04-10 13:39:52 -04:00
rustc_monomorphize Only collect mono items from reachable blocks 2024-04-07 14:36:42 -04:00
rustc_next_trait_solver Auto merge of #122077 - oli-obk:eager_opaque_checks4, r=lcnr 2024-04-08 23:01:50 +00:00
rustc_parse Rollup merge of #123223 - estebank:issue-123079, r=pnkfelix 2024-04-12 17:41:33 +02:00
rustc_parse_format
rustc_passes Actually create ranged int types in the type system. 2024-04-08 12:02:19 +00:00
rustc_pattern_analysis Actually create ranged int types in the type system. 2024-04-08 12:02:19 +00:00
rustc_privacy Actually create ranged int types in the type system. 2024-04-08 12:02:19 +00:00
rustc_query_impl move QueryKeyStringCache from rustc_middle to rustc_query_impl, where it actually used 2024-04-11 14:33:48 +03:00
rustc_query_system remove some things that do not need to be 2024-04-11 21:09:52 +02:00
rustc_resolve Rollup merge of #123204 - notriddle:notriddle/include-str-span, r=pnkfelix 2024-04-12 17:41:32 +02:00
rustc_sanitizers sanitizers: Create the rustc_sanitizers crate 2024-04-08 12:05:41 -07:00
rustc_serialize
rustc_session linker: Avoid some allocations in search directory iteration 2024-04-12 00:41:08 +03:00
rustc_smir Rollup merge of #123659 - celinval:smir-fix-intrinsic, r=oli-obk 2024-04-10 16:15:23 +02:00
rustc_span Rollup merge of #123654 - jieyouxu:question-mark-span, r=Nadrieril 2024-04-12 21:46:57 +02:00
rustc_symbol_mangling Rollup merge of #123649 - maurer:kcfi-v0, r=compiler-errors 2024-04-09 06:02:24 +02:00
rustc_target Auto merge of #123257 - ChrisDenton:enable-tls, r=fmease 2024-04-13 07:03:01 +00:00
rustc_trait_selection Add a helper for extending a span to include any trailing whitespace 2024-04-09 14:06:09 -04:00
rustc_traits
rustc_transmute Rollup merge of #123367 - jswrenn:layoutify, r=compiler-errors 2024-04-08 22:06:21 +02:00
rustc_ty_utils Handle const generic pattern types 2024-04-09 16:42:45 -03:00
rustc_type_ir introduce Mutability::ptr_str 2024-04-10 18:51:09 +02:00
stable_mir Rollup merge of #123659 - celinval:smir-fix-intrinsic, r=oli-obk 2024-04-10 16:15:23 +02:00