diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index cf550a2e5d8..8249d5142ed 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -987,6 +987,23 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { can_suggest_clone } + pub(crate) fn suggest_cloning( + &self, + err: &mut Diag<'_>, + ty: Ty<'tcx>, + expr: &hir::Expr<'_>, + span: Span, + ) { + if let Some(clone_trait_def) = self.infcx.tcx.lang_items().clone_trait() + && self + .infcx + .type_implements_trait(clone_trait_def, [ty], self.param_env) + .must_apply_modulo_regions() + { + self.suggest_cloning_inner(err, ty, expr, span); + } + } + pub(crate) fn clone_on_reference(&self, expr: &hir::Expr<'_>) -> Option { let typeck_results = self.infcx.tcx.typeck(self.mir_def_id()); if let hir::ExprKind::MethodCall(segment, rcvr, args, span) = expr.kind @@ -1002,7 +1019,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } - fn suggest_cloning(&self, err: &mut Diag<'_>, ty: Ty<'tcx>, expr: &hir::Expr<'_>, span: Span) { + fn suggest_cloning_inner( + &self, + err: &mut Diag<'_>, + ty: Ty<'tcx>, + expr: &hir::Expr<'_>, + span: Span, + ) { let tcx = self.infcx.tcx; // Try to find predicates on *generic params* that would allow copying `ty` let suggestion = @@ -1136,6 +1159,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { None, ); self.suggest_copy_for_type_in_cloned_ref(&mut err, place); + let typeck_results = self.infcx.tcx.typeck(self.mir_def_id()); + if let Some(expr) = self.find_expr(borrow_span) + && let Some(ty) = typeck_results.node_type_opt(expr.hir_id) + { + self.suggest_cloning(&mut err, ty, expr, borrow_span); + } self.buffer_error(err); } @@ -1553,22 +1582,32 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } for ty in types_to_constrain { - self.suggest_adding_bounds(err, ty, clone, body.span); - if let ty::Adt(..) = ty.kind() { - // The type doesn't implement Clone. - let trait_ref = ty::Binder::dummy(ty::TraitRef::new(self.infcx.tcx, clone, [ty])); - let obligation = Obligation::new( - self.infcx.tcx, - ObligationCause::dummy(), - self.param_env, - trait_ref, - ); - self.infcx.err_ctxt().suggest_derive( - &obligation, - err, - trait_ref.to_predicate(self.infcx.tcx), - ); - } + self.suggest_adding_bounds_or_derive(err, ty, clone, body.span); + } + } + + pub(crate) fn suggest_adding_bounds_or_derive( + &self, + err: &mut Diag<'_>, + ty: Ty<'tcx>, + def_id: DefId, + span: Span, + ) { + self.suggest_adding_bounds(err, ty, def_id, span); + if let ty::Adt(..) = ty.kind() { + // The type doesn't implement DefId. + let trait_ref = ty::Binder::dummy(ty::TraitRef::new(self.infcx.tcx, def_id, [ty])); + let obligation = Obligation::new( + self.infcx.tcx, + ObligationCause::dummy(), + self.param_env, + trait_ref, + ); + self.infcx.err_ctxt().suggest_derive( + &obligation, + err, + trait_ref.to_predicate(self.infcx.tcx), + ); } } diff --git a/tests/ui/associated-types/associated-types-outlives.stderr b/tests/ui/associated-types/associated-types-outlives.stderr index deeedd22266..dcd05ba9c2e 100644 --- a/tests/ui/associated-types/associated-types-outlives.stderr +++ b/tests/ui/associated-types/associated-types-outlives.stderr @@ -10,6 +10,11 @@ LL | drop(x); | ^ move out of `x` occurs here LL | return f(y); | - borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | 's: loop { y = denormalise(&x.clone()); break } + | ++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/binop/binop-move-semantics.stderr b/tests/ui/binop/binop-move-semantics.stderr index 1dd8c9a87d4..06dd84c3b9a 100644 --- a/tests/ui/binop/binop-move-semantics.stderr +++ b/tests/ui/binop/binop-move-semantics.stderr @@ -51,6 +51,11 @@ LL | x ... LL | use_mut(n); use_imm(m); | - borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let m = &x.clone(); + | ++++++++ error[E0505]: cannot move out of `y` because it is borrowed --> $DIR/binop-move-semantics.rs:23:5 diff --git a/tests/ui/borrowck/borrow-tuple-fields.stderr b/tests/ui/borrowck/borrow-tuple-fields.stderr index e324ebfb50f..277c335cfcc 100644 --- a/tests/ui/borrowck/borrow-tuple-fields.stderr +++ b/tests/ui/borrowck/borrow-tuple-fields.stderr @@ -10,6 +10,11 @@ LL | let y = x; LL | LL | r.use_ref(); | - borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let r = &x.0.clone(); + | ++++++++ error[E0502]: cannot borrow `x.0` as mutable because it is also borrowed as immutable --> $DIR/borrow-tuple-fields.rs:18:13 @@ -42,6 +47,11 @@ LL | let y = x; | ^ move out of `x` occurs here LL | r.use_ref(); | - borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let r = &x.0.clone(); + | ++++++++ error[E0502]: cannot borrow `x.0` as mutable because it is also borrowed as immutable --> $DIR/borrow-tuple-fields.rs:33:13 diff --git a/tests/ui/borrowck/borrowck-bad-nested-calls-move.stderr b/tests/ui/borrowck/borrowck-bad-nested-calls-move.stderr index e582ec605de..eb5e2fa89f8 100644 --- a/tests/ui/borrowck/borrowck-bad-nested-calls-move.stderr +++ b/tests/ui/borrowck/borrowck-bad-nested-calls-move.stderr @@ -10,6 +10,11 @@ LL | &*a, | --- borrow of `*a` occurs here LL | a); | ^ move out of `a` occurs here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | &*a.clone(), + | ++++++++ error[E0505]: cannot move out of `a` because it is borrowed --> $DIR/borrowck-bad-nested-calls-move.rs:32:9 @@ -22,6 +27,11 @@ LL | &*a, | --- borrow of `*a` occurs here LL | a); | ^ move out of `a` occurs here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | &*a.clone(), + | ++++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/borrowck/borrowck-field-sensitivity.stderr b/tests/ui/borrowck/borrowck-field-sensitivity.stderr index 11812847dd1..b30dd144a4d 100644 --- a/tests/ui/borrowck/borrowck-field-sensitivity.stderr +++ b/tests/ui/borrowck/borrowck-field-sensitivity.stderr @@ -49,6 +49,11 @@ LL | drop(x.b); | ^^^ move out of `x.b` occurs here LL | drop(**p); | --- borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let p = &x.b.clone(); + | ++++++++ error[E0505]: cannot move out of `x.b` because it is borrowed --> $DIR/borrowck-field-sensitivity.rs:41:14 @@ -61,6 +66,11 @@ LL | let _y = A { a: 3, .. x }; | ^^^^^^^^^^^^^^^^ move out of `x.b` occurs here LL | drop(**p); | --- borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let p = &x.b.clone(); + | ++++++++ error[E0499]: cannot borrow `x.a` as mutable more than once at a time --> $DIR/borrowck-field-sensitivity.rs:48:13 diff --git a/tests/ui/borrowck/borrowck-loan-blocks-move-cc.stderr b/tests/ui/borrowck/borrowck-loan-blocks-move-cc.stderr index 86479043a06..d9af5cf7d12 100644 --- a/tests/ui/borrowck/borrowck-loan-blocks-move-cc.stderr +++ b/tests/ui/borrowck/borrowck-loan-blocks-move-cc.stderr @@ -13,6 +13,11 @@ LL | println!("v={}", *v); LL | }); LL | w.use_ref(); | - borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let w = &v.clone(); + | ++++++++ error[E0505]: cannot move out of `v` because it is borrowed --> $DIR/borrowck-loan-blocks-move-cc.rs:24:19 @@ -29,6 +34,11 @@ LL | println!("v={}", *v); LL | }); LL | w.use_ref(); | - borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let w = &v.clone(); + | ++++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/borrowck/borrowck-loan-blocks-move.stderr b/tests/ui/borrowck/borrowck-loan-blocks-move.stderr index d1fbc5b47db..1698035f20f 100644 --- a/tests/ui/borrowck/borrowck-loan-blocks-move.stderr +++ b/tests/ui/borrowck/borrowck-loan-blocks-move.stderr @@ -9,6 +9,11 @@ LL | take(v); | ^ move out of `v` occurs here LL | w.use_ref(); | - borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let w = &v.clone(); + | ++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-move-from-subpath-of-borrowed-path.stderr b/tests/ui/borrowck/borrowck-move-from-subpath-of-borrowed-path.stderr index a41c4af98e7..b78c374c456 100644 --- a/tests/ui/borrowck/borrowck-move-from-subpath-of-borrowed-path.stderr +++ b/tests/ui/borrowck/borrowck-move-from-subpath-of-borrowed-path.stderr @@ -10,6 +10,11 @@ LL | let z = *a; | ^^ move out of `*a` occurs here LL | b.use_ref(); | - borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let b = &a.clone(); + | ++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-move-mut-base-ptr.stderr b/tests/ui/borrowck/borrowck-move-mut-base-ptr.stderr index 88eb6c8ceee..3e540a5dc98 100644 --- a/tests/ui/borrowck/borrowck-move-mut-base-ptr.stderr +++ b/tests/ui/borrowck/borrowck-move-mut-base-ptr.stderr @@ -10,6 +10,11 @@ LL | let t1 = t0; LL | *t1 = 22; LL | p.use_ref(); | - borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let p: &isize = &*t0.clone(); // Freezes `*t0` + | ++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-move-subcomponent.stderr b/tests/ui/borrowck/borrowck-move-subcomponent.stderr index 8408d99156a..5eb02ee2be9 100644 --- a/tests/ui/borrowck/borrowck-move-subcomponent.stderr +++ b/tests/ui/borrowck/borrowck-move-subcomponent.stderr @@ -9,6 +9,11 @@ LL | let S { x: ax } = a; | ^^ move out of `a.x` occurs here LL | f(pb); | -- borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let pb = &a.clone(); + | ++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-multiple-captures.stderr b/tests/ui/borrowck/borrowck-multiple-captures.stderr index 70abe7b346e..01b648ea647 100644 --- a/tests/ui/borrowck/borrowck-multiple-captures.stderr +++ b/tests/ui/borrowck/borrowck-multiple-captures.stderr @@ -14,6 +14,11 @@ LL | drop(x1); ... LL | borrow(&*p1); | ---- borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let p1 = &x1.clone(); + | ++++++++ error[E0505]: cannot move out of `x2` because it is borrowed --> $DIR/borrowck-multiple-captures.rs:12:19 @@ -30,6 +35,11 @@ LL | drop(x2); ... LL | borrow(&*p2); | ---- borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let p2 = &x2.clone(); + | ++++++++ error[E0382]: use of moved value: `x1` --> $DIR/borrowck-multiple-captures.rs:27:19 @@ -93,6 +103,11 @@ LL | drop(x); ... LL | borrow(&*p); | --- borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let p = &x.clone(); + | ++++++++ error[E0382]: use of moved value: `x` --> $DIR/borrowck-multiple-captures.rs:52:14 diff --git a/tests/ui/borrowck/borrowck-unary-move.stderr b/tests/ui/borrowck/borrowck-unary-move.stderr index e6c3869f67a..a4118b3d1a3 100644 --- a/tests/ui/borrowck/borrowck-unary-move.stderr +++ b/tests/ui/borrowck/borrowck-unary-move.stderr @@ -9,6 +9,11 @@ LL | free(x); | ^ move out of `x` occurs here LL | *y | -- borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let y = &*x.clone(); + | ++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/clone-on-ref.fixed b/tests/ui/borrowck/clone-on-ref.fixed index b6927ba590e..58339919696 100644 --- a/tests/ui/borrowck/clone-on-ref.fixed +++ b/tests/ui/borrowck/clone-on-ref.fixed @@ -9,7 +9,7 @@ fn foo(list: &mut Vec) { drop(cloned_items); } fn bar(x: T) { - let a = &x; + let a = &x.clone(); let b = a.clone(); drop(x); //~^ ERROR cannot move out of `x` because it is borrowed @@ -19,7 +19,7 @@ fn bar(x: T) { #[derive(Clone)] struct A; fn qux(x: A) { - let a = &x; + let a = &x.clone(); let b = a.clone(); drop(x); //~^ ERROR cannot move out of `x` because it is borrowed diff --git a/tests/ui/borrowck/clone-on-ref.stderr b/tests/ui/borrowck/clone-on-ref.stderr index ee4fcadf55a..732a9370fa7 100644 --- a/tests/ui/borrowck/clone-on-ref.stderr +++ b/tests/ui/borrowck/clone-on-ref.stderr @@ -36,6 +36,10 @@ help: consider further restricting this bound | LL | fn bar(x: T) { | +++++++ +help: consider cloning the value if the performance cost is acceptable + | +LL | let a = &x.clone(); + | ++++++++ error[E0505]: cannot move out of `x` because it is borrowed --> $DIR/clone-on-ref.rs:23:10 @@ -57,6 +61,10 @@ help: consider annotating `A` with `#[derive(Clone)]` LL + #[derive(Clone)] LL | struct A; | +help: consider cloning the value if the performance cost is acceptable + | +LL | let a = &x.clone(); + | ++++++++ error: aborting due to 3 previous errors diff --git a/tests/ui/btreemap/btreemap_dropck.stderr b/tests/ui/btreemap/btreemap_dropck.stderr index 805c2112bdc..e8f14552af2 100644 --- a/tests/ui/btreemap/btreemap_dropck.stderr +++ b/tests/ui/btreemap/btreemap_dropck.stderr @@ -9,6 +9,11 @@ LL | drop(s); | ^ move out of `s` occurs here LL | } | - borrow might be used here, when `_map` is dropped and runs the `Drop` code for type `BTreeMap` + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let _map = BTreeMap::from_iter([((), PrintOnDrop(&s.clone()))]); + | ++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/dropck/drop-with-active-borrows-1.stderr b/tests/ui/dropck/drop-with-active-borrows-1.stderr index 229514c6fee..7d1633267f0 100644 --- a/tests/ui/dropck/drop-with-active-borrows-1.stderr +++ b/tests/ui/dropck/drop-with-active-borrows-1.stderr @@ -9,6 +9,11 @@ LL | drop(a); | ^ move out of `a` occurs here LL | for s in &b { | -- borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let b: Vec<&str> = a.clone().lines().collect(); + | ++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0504.stderr b/tests/ui/error-codes/E0504.stderr index c8a48961cb3..9759e81a2c7 100644 --- a/tests/ui/error-codes/E0504.stderr +++ b/tests/ui/error-codes/E0504.stderr @@ -13,6 +13,11 @@ LL | println!("child function: {}", fancy_num.num); ... LL | println!("main function: {}", fancy_ref.num); | ------------- borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let fancy_ref = &fancy_num.clone(); + | ++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0505.stderr b/tests/ui/error-codes/E0505.stderr index 250680d2c1c..6808943796c 100644 --- a/tests/ui/error-codes/E0505.stderr +++ b/tests/ui/error-codes/E0505.stderr @@ -10,6 +10,11 @@ LL | eat(x); | ^ move out of `x` occurs here LL | _ref_to_val.use_ref(); | ----------- borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let _ref_to_val: &Value = &x.clone(); + | ++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/fn/implied-bounds-unnorm-associated-type-4.stderr b/tests/ui/fn/implied-bounds-unnorm-associated-type-4.stderr index 3be630e2b23..4e64ed6f482 100644 --- a/tests/ui/fn/implied-bounds-unnorm-associated-type-4.stderr +++ b/tests/ui/fn/implied-bounds-unnorm-associated-type-4.stderr @@ -10,6 +10,11 @@ LL | drop(x); LL | LL | println!("{}", y); | - borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let y = f(&x.clone(), ()); + | ++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/fn/implied-bounds-unnorm-associated-type-5.stderr b/tests/ui/fn/implied-bounds-unnorm-associated-type-5.stderr index bf6d77b6269..b898df0835c 100644 --- a/tests/ui/fn/implied-bounds-unnorm-associated-type-5.stderr +++ b/tests/ui/fn/implied-bounds-unnorm-associated-type-5.stderr @@ -27,6 +27,11 @@ LL | drop(x); | ^ move out of `x` occurs here LL | println!("{}", y); | - borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let y = f(&x.clone(), ()); + | ++++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/fn/implied-bounds-unnorm-associated-type.stderr b/tests/ui/fn/implied-bounds-unnorm-associated-type.stderr index c2a8fa741ca..2a7431305fe 100644 --- a/tests/ui/fn/implied-bounds-unnorm-associated-type.stderr +++ b/tests/ui/fn/implied-bounds-unnorm-associated-type.stderr @@ -10,6 +10,11 @@ LL | drop(x); LL | LL | println!("{}", y); | - borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let y = f(&x.clone(), ()); + | ++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/nll/closure-access-spans.stderr b/tests/ui/nll/closure-access-spans.stderr index 3e98fbd5e1d..a8024a8c20b 100644 --- a/tests/ui/nll/closure-access-spans.stderr +++ b/tests/ui/nll/closure-access-spans.stderr @@ -57,6 +57,11 @@ LL | || x; | move out of `x` occurs here LL | r.use_ref(); | - borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let r = &x.clone(); + | ++++++++ error[E0382]: borrow of moved value: `x` --> $DIR/closure-access-spans.rs:35:5 diff --git a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr index a033cc0655e..62896e1fd03 100644 --- a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr +++ b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr @@ -10,6 +10,11 @@ LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr; LL | _x1 = U; LL | drop(hold_all); | -------- borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let hold_all = &arr.clone(); + | ++++++++ error[E0384]: cannot assign twice to immutable variable `_x1` --> $DIR/borrowck-move-ref-pattern.rs:9:5 diff --git a/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr b/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr index 29a606c4f01..bac7801f7f4 100644 --- a/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr +++ b/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr @@ -57,6 +57,11 @@ LL | f(Box::new(|a| { LL | LL | foo(f); | - move occurs due to use in closure + | +help: consider cloning the value if the performance cost is acceptable + | +LL | f.clone()(Box::new(|a| { + | ++++++++ error: aborting due to 5 previous errors diff --git a/tests/ui/span/send-is-not-static-std-sync.stderr b/tests/ui/span/send-is-not-static-std-sync.stderr index 46534b39168..1f4462f4fe7 100644 --- a/tests/ui/span/send-is-not-static-std-sync.stderr +++ b/tests/ui/span/send-is-not-static-std-sync.stderr @@ -11,6 +11,11 @@ LL | drop(y); ... LL | *lock.lock().unwrap() = &z; | ---- borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | *lock.lock().unwrap() = &*y.clone(); + | ++++++++ error[E0597]: `z` does not live long enough --> $DIR/send-is-not-static-std-sync.rs:16:33 @@ -38,6 +43,11 @@ LL | drop(y); ... LL | *lock.write().unwrap() = &z; | ---- borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | *lock.write().unwrap() = &*y.clone(); + | ++++++++ error[E0597]: `z` does not live long enough --> $DIR/send-is-not-static-std-sync.rs:30:34 @@ -65,6 +75,11 @@ LL | drop(y); ... LL | tx.send(&z).unwrap(); | -- borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | tx.send(&*y.clone()); + | ++++++++ error[E0597]: `z` does not live long enough --> $DIR/send-is-not-static-std-sync.rs:46:17 diff --git a/tests/ui/suggestions/borrow-for-loop-head.stderr b/tests/ui/suggestions/borrow-for-loop-head.stderr index 0f179438a12..55fcb44168c 100644 --- a/tests/ui/suggestions/borrow-for-loop-head.stderr +++ b/tests/ui/suggestions/borrow-for-loop-head.stderr @@ -7,6 +7,11 @@ LL | for i in &a { | -- borrow of `a` occurs here LL | for j in a { | ^ move out of `a` occurs here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | for i in &a.clone() { + | ++++++++ error[E0382]: use of moved value: `a` --> $DIR/borrow-for-loop-head.rs:4:18 diff --git a/tests/ui/unop-move-semantics.stderr b/tests/ui/unop-move-semantics.stderr index 187dd66b2fe..a6549d84a8a 100644 --- a/tests/ui/unop-move-semantics.stderr +++ b/tests/ui/unop-move-semantics.stderr @@ -33,6 +33,11 @@ LL | !x; ... LL | use_mut(n); use_imm(m); | - borrow later used here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let m = &x.clone(); + | ++++++++ error[E0505]: cannot move out of `y` because it is borrowed --> $DIR/unop-move-semantics.rs:17:6 diff --git a/tests/ui/variance/variance-issue-20533.stderr b/tests/ui/variance/variance-issue-20533.stderr index 258f67db5ce..7fed947972f 100644 --- a/tests/ui/variance/variance-issue-20533.stderr +++ b/tests/ui/variance/variance-issue-20533.stderr @@ -9,6 +9,11 @@ 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.clone()); + | ++++++++ error[E0505]: cannot move out of `a` because it is borrowed --> $DIR/variance-issue-20533.rs:34:14 @@ -21,6 +26,11 @@ 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 = bar(&a.clone()); + | ++++++++ error[E0505]: cannot move out of `a` because it is borrowed --> $DIR/variance-issue-20533.rs:40:14 @@ -33,6 +43,11 @@ 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 = baz(&a.clone()); + | ++++++++ error: aborting due to 3 previous errors