Rollup merge of #144201 - estebank:suggest-clone, r=SparrowLii
Mention type that could be `Clone` but isn't in more cases
When encountering a moved value of a type that isn't `Clone` because of unmet obligations, but where all the unmet predicates reference crate-local types, mention them and suggest cloning, as we do in other cases already:
```
error[E0507]: cannot move out of `foo`, a captured variable in an `Fn` closure
--> f111.rs:14:25
|
13 | fn do_stuff(foo: Option<Foo>) {
| --- captured outer variable
14 | require_fn_trait(|| async {
| -- ^^^^^ `foo` is moved here
| |
| captured by this `Fn` closure
15 | if foo.map_or(false, |f| f.foo()) {
| ---
| |
| variable moved due to use in coroutine
| move occurs because `foo` has type `Option<Foo>`, which does not implement the `Copy` trait
|
note: if `Foo` implemented `Clone`, you could clone the value
--> f111.rs:4:1
|
4 | struct Foo;
| ^^^^^^^^^^ consider implementing `Clone` for this type
...
15 | if foo.map_or(false, |f| f.foo()) {
| --- you could clone this value
```
CC rust-lang/rust#68119.
This commit is contained in:
@@ -1290,6 +1290,58 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
|||||||
span,
|
span,
|
||||||
format!("if `{ty}` implemented `Clone`, you could clone the value"),
|
format!("if `{ty}` implemented `Clone`, you could clone the value"),
|
||||||
);
|
);
|
||||||
|
} else if let ty::Adt(_, _) = ty.kind()
|
||||||
|
&& let Some(clone_trait) = self.infcx.tcx.lang_items().clone_trait()
|
||||||
|
{
|
||||||
|
// For cases like `Option<NonClone>`, where `Option<T>: Clone` if `T: Clone`, we point
|
||||||
|
// at the types that should be `Clone`.
|
||||||
|
let ocx = ObligationCtxt::new_with_diagnostics(self.infcx);
|
||||||
|
let cause = ObligationCause::misc(expr.span, self.mir_def_id());
|
||||||
|
ocx.register_bound(cause, self.infcx.param_env, ty, clone_trait);
|
||||||
|
let errors = ocx.select_all_or_error();
|
||||||
|
if errors.iter().all(|error| {
|
||||||
|
match error.obligation.predicate.as_clause().and_then(|c| c.as_trait_clause()) {
|
||||||
|
Some(clause) => match clause.self_ty().skip_binder().kind() {
|
||||||
|
ty::Adt(def, _) => def.did().is_local() && clause.def_id() == clone_trait,
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
None => false,
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
let mut type_spans = vec![];
|
||||||
|
let mut types = FxIndexSet::default();
|
||||||
|
for clause in errors
|
||||||
|
.iter()
|
||||||
|
.filter_map(|e| e.obligation.predicate.as_clause())
|
||||||
|
.filter_map(|c| c.as_trait_clause())
|
||||||
|
{
|
||||||
|
let ty::Adt(def, _) = clause.self_ty().skip_binder().kind() else { continue };
|
||||||
|
type_spans.push(self.infcx.tcx.def_span(def.did()));
|
||||||
|
types.insert(
|
||||||
|
self.infcx
|
||||||
|
.tcx
|
||||||
|
.short_string(clause.self_ty().skip_binder(), &mut err.long_ty_path()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let mut span: MultiSpan = type_spans.clone().into();
|
||||||
|
for sp in type_spans {
|
||||||
|
span.push_span_label(sp, "consider implementing `Clone` for this type");
|
||||||
|
}
|
||||||
|
span.push_span_label(expr.span, "you could clone this value");
|
||||||
|
let types: Vec<_> = types.into_iter().collect();
|
||||||
|
let msg = match &types[..] {
|
||||||
|
[only] => format!("`{only}`"),
|
||||||
|
[head @ .., last] => format!(
|
||||||
|
"{} and `{last}`",
|
||||||
|
head.iter().map(|t| format!("`{t}`")).collect::<Vec<_>>().join(", ")
|
||||||
|
),
|
||||||
|
[] => unreachable!(),
|
||||||
|
};
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
format!("if {msg} implemented `Clone`, you could clone the value"),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,15 @@ LL | drop(t);
|
|||||||
| - value moved here
|
| - value moved here
|
||||||
LL | t.b = Some(u);
|
LL | t.b = Some(u);
|
||||||
| ^^^ value assigned here after move
|
| ^^^ value assigned here after move
|
||||||
|
|
|
||||||
|
note: if `Test2` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/borrowck-partial-reinit-1.rs:3:1
|
||||||
|
|
|
||||||
|
LL | struct Test2 {
|
||||||
|
| ^^^^^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | drop(t);
|
||||||
|
| - you could clone this value
|
||||||
|
|
||||||
error[E0382]: assign of moved value: `t`
|
error[E0382]: assign of moved value: `t`
|
||||||
--> $DIR/borrowck-partial-reinit-1.rs:33:5
|
--> $DIR/borrowck-partial-reinit-1.rs:33:5
|
||||||
@@ -19,6 +28,15 @@ LL | drop(t);
|
|||||||
| - value moved here
|
| - value moved here
|
||||||
LL | t.0 = Some(u);
|
LL | t.0 = Some(u);
|
||||||
| ^^^ value assigned here after move
|
| ^^^ value assigned here after move
|
||||||
|
|
|
||||||
|
note: if `Test3` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/borrowck-partial-reinit-1.rs:7:1
|
||||||
|
|
|
||||||
|
LL | struct Test3(Option<Test>);
|
||||||
|
| ^^^^^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | drop(t);
|
||||||
|
| - you could clone this value
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,15 @@ LL | let mut u = Test { a: 2, b: Some(Box::new(t))};
|
|||||||
| - value moved here
|
| - value moved here
|
||||||
LL | t.b = Some(Box::new(u));
|
LL | t.b = Some(Box::new(u));
|
||||||
| ^^^ value assigned here after move
|
| ^^^ value assigned here after move
|
||||||
|
|
|
||||||
|
note: if `Test` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/borrowck-partial-reinit-2.rs:1:1
|
||||||
|
|
|
||||||
|
LL | struct Test {
|
||||||
|
| ^^^^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | let mut u = Test { a: 2, b: Some(Box::new(t))};
|
||||||
|
| - you could clone this value
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,15 @@ LL | let a = u.a;
|
|||||||
| --- value moved here
|
| --- value moved here
|
||||||
LL | let a = u.a;
|
LL | let a = u.a;
|
||||||
| ^^^ value used here after move
|
| ^^^ value used here after move
|
||||||
|
|
|
||||||
|
note: if `U` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/borrowck-union-move-assign.rs:7:1
|
||||||
|
|
|
||||||
|
LL | union U {
|
||||||
|
| ^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | let a = u.a;
|
||||||
|
| --- you could clone this value
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,15 @@ LL | let a = u.n1;
|
|||||||
| ---- value moved here
|
| ---- value moved here
|
||||||
LL | let a = u.n1;
|
LL | let a = u.n1;
|
||||||
| ^^^^ value used here after move
|
| ^^^^ value used here after move
|
||||||
|
|
|
||||||
|
note: if `Unn` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/borrowck-union-move.rs:7:1
|
||||||
|
|
|
||||||
|
LL | union Unn {
|
||||||
|
| ^^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | let a = u.n1;
|
||||||
|
| ---- you could clone this value
|
||||||
|
|
||||||
error[E0382]: use of moved value: `u`
|
error[E0382]: use of moved value: `u`
|
||||||
--> $DIR/borrowck-union-move.rs:31:21
|
--> $DIR/borrowck-union-move.rs:31:21
|
||||||
@@ -17,6 +26,15 @@ LL | let a = u.n1;
|
|||||||
| ---- value moved here
|
| ---- value moved here
|
||||||
LL | let a = u;
|
LL | let a = u;
|
||||||
| ^ value used here after move
|
| ^ value used here after move
|
||||||
|
|
|
||||||
|
note: if `Unn` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/borrowck-union-move.rs:7:1
|
||||||
|
|
|
||||||
|
LL | union Unn {
|
||||||
|
| ^^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | let a = u.n1;
|
||||||
|
| ---- you could clone this value
|
||||||
|
|
||||||
error[E0382]: use of moved value: `u`
|
error[E0382]: use of moved value: `u`
|
||||||
--> $DIR/borrowck-union-move.rs:36:21
|
--> $DIR/borrowck-union-move.rs:36:21
|
||||||
@@ -27,6 +45,15 @@ LL | let a = u.n1;
|
|||||||
| ---- value moved here
|
| ---- value moved here
|
||||||
LL | let a = u.n2;
|
LL | let a = u.n2;
|
||||||
| ^^^^ value used here after move
|
| ^^^^ value used here after move
|
||||||
|
|
|
||||||
|
note: if `Unn` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/borrowck-union-move.rs:7:1
|
||||||
|
|
|
||||||
|
LL | union Unn {
|
||||||
|
| ^^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | let a = u.n1;
|
||||||
|
| ---- you could clone this value
|
||||||
|
|
||||||
error[E0382]: use of moved value: `u`
|
error[E0382]: use of moved value: `u`
|
||||||
--> $DIR/borrowck-union-move.rs:63:21
|
--> $DIR/borrowck-union-move.rs:63:21
|
||||||
@@ -37,6 +64,15 @@ LL | let a = u.n;
|
|||||||
| --- value moved here
|
| --- value moved here
|
||||||
LL | let a = u.n;
|
LL | let a = u.n;
|
||||||
| ^^^ value used here after move
|
| ^^^ value used here after move
|
||||||
|
|
|
||||||
|
note: if `Ucn` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/borrowck-union-move.rs:15:1
|
||||||
|
|
|
||||||
|
LL | union Ucn {
|
||||||
|
| ^^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | let a = u.n;
|
||||||
|
| --- you could clone this value
|
||||||
|
|
||||||
error[E0382]: use of moved value: `u`
|
error[E0382]: use of moved value: `u`
|
||||||
--> $DIR/borrowck-union-move.rs:68:21
|
--> $DIR/borrowck-union-move.rs:68:21
|
||||||
@@ -47,6 +83,15 @@ LL | let a = u.n;
|
|||||||
| --- value moved here
|
| --- value moved here
|
||||||
LL | let a = u.c;
|
LL | let a = u.c;
|
||||||
| ^^^ value used here after move
|
| ^^^ value used here after move
|
||||||
|
|
|
||||||
|
note: if `Ucn` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/borrowck-union-move.rs:15:1
|
||||||
|
|
|
||||||
|
LL | union Ucn {
|
||||||
|
| ^^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | let a = u.n;
|
||||||
|
| --- you could clone this value
|
||||||
|
|
||||||
error[E0382]: use of moved value: `u`
|
error[E0382]: use of moved value: `u`
|
||||||
--> $DIR/borrowck-union-move.rs:83:21
|
--> $DIR/borrowck-union-move.rs:83:21
|
||||||
@@ -57,6 +102,15 @@ LL | let a = u.n;
|
|||||||
| --- value moved here
|
| --- value moved here
|
||||||
LL | let a = u;
|
LL | let a = u;
|
||||||
| ^ value used here after move
|
| ^ value used here after move
|
||||||
|
|
|
||||||
|
note: if `Ucn` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/borrowck-union-move.rs:15:1
|
||||||
|
|
|
||||||
|
LL | union Ucn {
|
||||||
|
| ^^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | let a = u.n;
|
||||||
|
| --- you could clone this value
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,15 @@ LL | drop(u);
|
|||||||
| - value moved here
|
| - value moved here
|
||||||
LL | u.0 = S(1);
|
LL | u.0 = S(1);
|
||||||
| ^^^^^^^^^^ value partially assigned here after move
|
| ^^^^^^^^^^ value partially assigned here after move
|
||||||
|
|
|
||||||
|
note: if `Tpair` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:6:1
|
||||||
|
|
|
||||||
|
LL | struct Tpair(S, i32);
|
||||||
|
| ^^^^^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | drop(u);
|
||||||
|
| - you could clone this value
|
||||||
|
|
||||||
error[E0382]: assign to part of moved value: `v`
|
error[E0382]: assign to part of moved value: `v`
|
||||||
--> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:31:9
|
--> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:31:9
|
||||||
@@ -27,6 +36,15 @@ LL | drop(v);
|
|||||||
| - value moved here
|
| - value moved here
|
||||||
LL | v.x = S(1);
|
LL | v.x = S(1);
|
||||||
| ^^^^^^^^^^ value partially assigned here after move
|
| ^^^^^^^^^^ value partially assigned here after move
|
||||||
|
|
|
||||||
|
note: if `Spair` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:7:1
|
||||||
|
|
|
||||||
|
LL | struct Spair { x: S, y: i32 }
|
||||||
|
| ^^^^^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | drop(v);
|
||||||
|
| - you could clone this value
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,15 @@ LL | drop(u);
|
|||||||
| - value moved here
|
| - value moved here
|
||||||
LL | u.0 = S(1);
|
LL | u.0 = S(1);
|
||||||
| ^^^^^^^^^^ value partially assigned here after move
|
| ^^^^^^^^^^ value partially assigned here after move
|
||||||
|
|
|
||||||
|
note: if `Tpair` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/issue-54499-field-mutation-of-moved-out.rs:6:1
|
||||||
|
|
|
||||||
|
LL | struct Tpair(S, i32);
|
||||||
|
| ^^^^^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | drop(u);
|
||||||
|
| - you could clone this value
|
||||||
|
|
||||||
error[E0594]: cannot assign to `u.1`, as `u` is not declared as mutable
|
error[E0594]: cannot assign to `u.1`, as `u` is not declared as mutable
|
||||||
--> $DIR/issue-54499-field-mutation-of-moved-out.rs:27:9
|
--> $DIR/issue-54499-field-mutation-of-moved-out.rs:27:9
|
||||||
@@ -82,6 +91,15 @@ LL | drop(v);
|
|||||||
| - value moved here
|
| - value moved here
|
||||||
LL | v.x = S(1);
|
LL | v.x = S(1);
|
||||||
| ^^^^^^^^^^ value partially assigned here after move
|
| ^^^^^^^^^^ value partially assigned here after move
|
||||||
|
|
|
||||||
|
note: if `Spair` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/issue-54499-field-mutation-of-moved-out.rs:7:1
|
||||||
|
|
|
||||||
|
LL | struct Spair { x: S, y: i32 }
|
||||||
|
| ^^^^^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | drop(v);
|
||||||
|
| - you could clone this value
|
||||||
|
|
||||||
error[E0594]: cannot assign to `v.y`, as `v` is not declared as mutable
|
error[E0594]: cannot assign to `v.y`, as `v` is not declared as mutable
|
||||||
--> $DIR/issue-54499-field-mutation-of-moved-out.rs:38:9
|
--> $DIR/issue-54499-field-mutation-of-moved-out.rs:38:9
|
||||||
|
|||||||
@@ -4,6 +4,14 @@ error[E0507]: cannot move out of `*array` which is behind a shared reference
|
|||||||
LL | *array
|
LL | *array
|
||||||
| ^^^^^^ move occurs because `*array` has type `Vec<Value>`, which does not implement the `Copy` trait
|
| ^^^^^^ move occurs because `*array` has type `Vec<Value>`, which does not implement the `Copy` trait
|
||||||
|
|
|
|
||||||
|
note: if `Value` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/issue-54597-reject-move-out-of-borrow-via-pat.rs:4:1
|
||||||
|
|
|
||||||
|
LL | struct Value;
|
||||||
|
| ^^^^^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | *array
|
||||||
|
| ------ you could clone this value
|
||||||
help: consider removing the dereference here
|
help: consider removing the dereference here
|
||||||
|
|
|
|
||||||
LL - *array
|
LL - *array
|
||||||
|
|||||||
@@ -26,6 +26,15 @@ LL | E::Number(_) if let E::String(s) = *value => { }
|
|||||||
...
|
...
|
||||||
LL | let x = value;
|
LL | let x = value;
|
||||||
| ^^^^^ value used here after move
|
| ^^^^^ value used here after move
|
||||||
|
|
|
||||||
|
note: if `E` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/if-let-guards-errors.rs:32:1
|
||||||
|
|
|
||||||
|
LL | E::Number(_) if let E::String(s) = *value => { }
|
||||||
|
| ------ you could clone this value
|
||||||
|
...
|
||||||
|
LL | enum E {
|
||||||
|
| ^^^^^^ consider implementing `Clone` for this type
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,15 @@ LL | E::Number(_) if let E::String(s) = *value => { }
|
|||||||
...
|
...
|
||||||
LL | let x = value;
|
LL | let x = value;
|
||||||
| ^^^^^ value used here after move
|
| ^^^^^ value used here after move
|
||||||
|
|
|
||||||
|
note: if `E` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/if-let-guards-errors.rs:32:1
|
||||||
|
|
|
||||||
|
LL | E::Number(_) if let E::String(s) = *value => { }
|
||||||
|
| ------ you could clone this value
|
||||||
|
...
|
||||||
|
LL | enum E {
|
||||||
|
| ^^^^^^ consider implementing `Clone` for this type
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,14 @@ LL | let mut copy: Vec<U> = map.clone().into_values().collect();
|
|||||||
|
|
|
|
||||||
note: `HashMap::<K, V, S>::into_values` takes ownership of the receiver `self`, which moves value
|
note: `HashMap::<K, V, S>::into_values` takes ownership of the receiver `self`, which moves value
|
||||||
--> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL
|
--> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL
|
||||||
|
note: if `Hash128_1` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/suggest-clone-when-some-obligation-is-unmet.rs:8:1
|
||||||
|
|
|
||||||
|
LL | pub struct Hash128_1;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | let mut copy: Vec<U> = map.clone().into_values().collect();
|
||||||
|
| ----------- you could clone this value
|
||||||
help: you could `clone` the value and consume it, if the `Hash128_1: Clone` trait bound could be satisfied
|
help: you could `clone` the value and consume it, if the `Hash128_1: Clone` trait bound could be satisfied
|
||||||
|
|
|
|
||||||
LL - let mut copy: Vec<U> = map.clone().into_values().collect();
|
LL - let mut copy: Vec<U> = map.clone().into_values().collect();
|
||||||
|
|||||||
@@ -27,6 +27,15 @@ LL | drop(d);
|
|||||||
| - value moved here
|
| - value moved here
|
||||||
LL | d.x = 10;
|
LL | d.x = 10;
|
||||||
| ^^^^^^^^ value assigned here after move
|
| ^^^^^^^^ value assigned here after move
|
||||||
|
|
|
||||||
|
note: if `D` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/issue-21232-partial-init-and-erroneous-use.rs:11:1
|
||||||
|
|
|
||||||
|
LL | struct D {
|
||||||
|
| ^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | drop(d);
|
||||||
|
| - you could clone this value
|
||||||
|
|
||||||
error[E0381]: partially assigned binding `d` isn't fully initialized
|
error[E0381]: partially assigned binding `d` isn't fully initialized
|
||||||
--> $DIR/issue-21232-partial-init-and-erroneous-use.rs:45:5
|
--> $DIR/issue-21232-partial-init-and-erroneous-use.rs:45:5
|
||||||
@@ -57,6 +66,15 @@ LL | drop(d);
|
|||||||
| - value moved here
|
| - value moved here
|
||||||
LL | d.s.y = 20;
|
LL | d.s.y = 20;
|
||||||
| ^^^^^^^^^^ value partially assigned here after move
|
| ^^^^^^^^^^ value partially assigned here after move
|
||||||
|
|
|
||||||
|
note: if `D` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/issue-21232-partial-init-and-erroneous-use.rs:11:1
|
||||||
|
|
|
||||||
|
LL | struct D {
|
||||||
|
| ^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | drop(d);
|
||||||
|
| - you could clone this value
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
|||||||
@@ -146,6 +146,15 @@ LL | m!((ref mut borrow, mov) = tup0);
|
|||||||
...
|
...
|
||||||
LL | drop(&tup0);
|
LL | drop(&tup0);
|
||||||
| ^^^^^ value borrowed here after move
|
| ^^^^^ value borrowed here after move
|
||||||
|
|
|
||||||
|
note: if `S` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/move-ref-patterns-closure-captures-inside.rs:2:5
|
||||||
|
|
|
||||||
|
LL | struct S; // Not `Copy`.
|
||||||
|
| ^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | m!((ref mut borrow, mov) = tup0);
|
||||||
|
| ---- you could clone this value
|
||||||
|
|
||||||
error[E0382]: borrow of moved value: `tup1`
|
error[E0382]: borrow of moved value: `tup1`
|
||||||
--> $DIR/move-ref-patterns-closure-captures-inside.rs:76:10
|
--> $DIR/move-ref-patterns-closure-captures-inside.rs:76:10
|
||||||
@@ -161,6 +170,15 @@ LL | m!((mov, _, ref mut borrow) = tup1);
|
|||||||
...
|
...
|
||||||
LL | drop(&tup1);
|
LL | drop(&tup1);
|
||||||
| ^^^^^ value borrowed here after move
|
| ^^^^^ value borrowed here after move
|
||||||
|
|
|
||||||
|
note: if `S` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/move-ref-patterns-closure-captures-inside.rs:2:5
|
||||||
|
|
|
||||||
|
LL | struct S; // Not `Copy`.
|
||||||
|
| ^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | m!((mov, _, ref mut borrow) = tup1);
|
||||||
|
| ---- you could clone this value
|
||||||
|
|
||||||
error[E0382]: borrow of moved value: `tup2`
|
error[E0382]: borrow of moved value: `tup2`
|
||||||
--> $DIR/move-ref-patterns-closure-captures-inside.rs:77:10
|
--> $DIR/move-ref-patterns-closure-captures-inside.rs:77:10
|
||||||
@@ -176,6 +194,15 @@ LL | m!((ref borrow, mov) = tup2);
|
|||||||
...
|
...
|
||||||
LL | drop(&tup2);
|
LL | drop(&tup2);
|
||||||
| ^^^^^ value borrowed here after move
|
| ^^^^^ value borrowed here after move
|
||||||
|
|
|
||||||
|
note: if `S` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/move-ref-patterns-closure-captures-inside.rs:2:5
|
||||||
|
|
|
||||||
|
LL | struct S; // Not `Copy`.
|
||||||
|
| ^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | m!((ref borrow, mov) = tup2);
|
||||||
|
| ---- you could clone this value
|
||||||
|
|
||||||
error[E0382]: borrow of moved value: `tup3`
|
error[E0382]: borrow of moved value: `tup3`
|
||||||
--> $DIR/move-ref-patterns-closure-captures-inside.rs:78:10
|
--> $DIR/move-ref-patterns-closure-captures-inside.rs:78:10
|
||||||
@@ -191,6 +218,15 @@ LL | m!((mov, _, ref borrow) = tup3);
|
|||||||
...
|
...
|
||||||
LL | drop(&tup3);
|
LL | drop(&tup3);
|
||||||
| ^^^^^ value borrowed here after move
|
| ^^^^^ value borrowed here after move
|
||||||
|
|
|
||||||
|
note: if `S` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/move-ref-patterns-closure-captures-inside.rs:2:5
|
||||||
|
|
|
||||||
|
LL | struct S; // Not `Copy`.
|
||||||
|
| ^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | m!((mov, _, ref borrow) = tup3);
|
||||||
|
| ---- you could clone this value
|
||||||
|
|
||||||
error[E0382]: borrow of moved value: `tup4`
|
error[E0382]: borrow of moved value: `tup4`
|
||||||
--> $DIR/move-ref-patterns-closure-captures-inside.rs:79:21
|
--> $DIR/move-ref-patterns-closure-captures-inside.rs:79:21
|
||||||
@@ -206,6 +242,15 @@ LL | m!((ref borrow, mov) = tup4);
|
|||||||
...
|
...
|
||||||
LL | m!((ref x, _) = &tup4);
|
LL | m!((ref x, _) = &tup4);
|
||||||
| ^^^^^ value borrowed here after move
|
| ^^^^^ value borrowed here after move
|
||||||
|
|
|
||||||
|
note: if `S` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/move-ref-patterns-closure-captures-inside.rs:2:5
|
||||||
|
|
|
||||||
|
LL | struct S; // Not `Copy`.
|
||||||
|
| ^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | m!((ref borrow, mov) = tup4);
|
||||||
|
| ---- you could clone this value
|
||||||
|
|
||||||
error[E0382]: borrow of moved value: `arr0`
|
error[E0382]: borrow of moved value: `arr0`
|
||||||
--> $DIR/move-ref-patterns-closure-captures-inside.rs:80:10
|
--> $DIR/move-ref-patterns-closure-captures-inside.rs:80:10
|
||||||
@@ -221,6 +266,15 @@ LL | m!([mov @ .., ref borrow] = arr0);
|
|||||||
...
|
...
|
||||||
LL | drop(&arr0);
|
LL | drop(&arr0);
|
||||||
| ^^^^^ value borrowed here after move
|
| ^^^^^ value borrowed here after move
|
||||||
|
|
|
||||||
|
note: if `S` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/move-ref-patterns-closure-captures-inside.rs:2:5
|
||||||
|
|
|
||||||
|
LL | struct S; // Not `Copy`.
|
||||||
|
| ^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | m!([mov @ .., ref borrow] = arr0);
|
||||||
|
| ---- you could clone this value
|
||||||
|
|
||||||
error[E0382]: borrow of moved value: `arr1`
|
error[E0382]: borrow of moved value: `arr1`
|
||||||
--> $DIR/move-ref-patterns-closure-captures-inside.rs:81:35
|
--> $DIR/move-ref-patterns-closure-captures-inside.rs:81:35
|
||||||
@@ -236,6 +290,15 @@ LL | m!([_, ref mut borrow @ .., _, mov] = arr1);
|
|||||||
...
|
...
|
||||||
LL | m!([_, mov1, mov2, mov3, _] = &arr1);
|
LL | m!([_, mov1, mov2, mov3, _] = &arr1);
|
||||||
| ^^^^^ value borrowed here after move
|
| ^^^^^ value borrowed here after move
|
||||||
|
|
|
||||||
|
note: if `S` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/move-ref-patterns-closure-captures-inside.rs:2:5
|
||||||
|
|
|
||||||
|
LL | struct S; // Not `Copy`.
|
||||||
|
| ^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | m!([_, ref mut borrow @ .., _, mov] = arr1);
|
||||||
|
| ---- you could clone this value
|
||||||
|
|
||||||
error[E0382]: borrow of moved value: `arr2`
|
error[E0382]: borrow of moved value: `arr2`
|
||||||
--> $DIR/move-ref-patterns-closure-captures-inside.rs:82:10
|
--> $DIR/move-ref-patterns-closure-captures-inside.rs:82:10
|
||||||
@@ -251,6 +314,15 @@ LL | m!([mov @ .., ref borrow] = arr2);
|
|||||||
...
|
...
|
||||||
LL | drop(&arr2);
|
LL | drop(&arr2);
|
||||||
| ^^^^^ value borrowed here after move
|
| ^^^^^ value borrowed here after move
|
||||||
|
|
|
||||||
|
note: if `S` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/move-ref-patterns-closure-captures-inside.rs:2:5
|
||||||
|
|
|
||||||
|
LL | struct S; // Not `Copy`.
|
||||||
|
| ^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | m!([mov @ .., ref borrow] = arr2);
|
||||||
|
| ---- you could clone this value
|
||||||
|
|
||||||
error[E0382]: borrow of moved value: `arr3`
|
error[E0382]: borrow of moved value: `arr3`
|
||||||
--> $DIR/move-ref-patterns-closure-captures-inside.rs:83:35
|
--> $DIR/move-ref-patterns-closure-captures-inside.rs:83:35
|
||||||
@@ -265,6 +337,15 @@ LL | m!([_, ref borrow @ .., _, mov] = arr3);
|
|||||||
...
|
...
|
||||||
LL | m!([_, mov1, mov2, mov3, _] = &arr3);
|
LL | m!([_, mov1, mov2, mov3, _] = &arr3);
|
||||||
| ^^^^^ value borrowed here after move
|
| ^^^^^ value borrowed here after move
|
||||||
|
|
|
||||||
|
note: if `S` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/move-ref-patterns-closure-captures-inside.rs:2:5
|
||||||
|
|
|
||||||
|
LL | struct S; // Not `Copy`.
|
||||||
|
| ^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | m!([_, ref borrow @ .., _, mov] = arr3);
|
||||||
|
| ---- you could clone this value
|
||||||
|
|
||||||
error[E0382]: borrow of moved value: `tup0`
|
error[E0382]: borrow of moved value: `tup0`
|
||||||
--> $DIR/move-ref-patterns-closure-captures-inside.rs:111:10
|
--> $DIR/move-ref-patterns-closure-captures-inside.rs:111:10
|
||||||
|
|||||||
@@ -3,6 +3,15 @@ error[E0507]: cannot move out of static item `BAR`
|
|||||||
|
|
|
|
||||||
LL | test(BAR);
|
LL | test(BAR);
|
||||||
| ^^^ move occurs because `BAR` has type `Foo`, which does not implement the `Copy` trait
|
| ^^^ move occurs because `BAR` has type `Foo`, which does not implement the `Copy` trait
|
||||||
|
|
|
||||||
|
note: if `Foo` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/static-items-cant-move.rs:5:1
|
||||||
|
|
|
||||||
|
LL | struct Foo {
|
||||||
|
| ^^^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | test(BAR);
|
||||||
|
| --- you could clone this value
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,15 @@ LL | move || {
|
|||||||
LL |
|
LL |
|
||||||
LL | var = Some(NotCopyable);
|
LL | var = Some(NotCopyable);
|
||||||
| --- variable moved due to use in closure
|
| --- variable moved due to use in closure
|
||||||
|
|
|
||||||
|
note: if `NotCopyable` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/option-content-move2.rs:1:1
|
||||||
|
|
|
||||||
|
LL | struct NotCopyable;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | var = Some(NotCopyable);
|
||||||
|
| --- you could clone this value
|
||||||
|
|
||||||
error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure
|
error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure
|
||||||
--> $DIR/option-content-move2.rs:21:9
|
--> $DIR/option-content-move2.rs:21:9
|
||||||
|
|||||||
@@ -31,6 +31,15 @@ LL | let a = u.x;
|
|||||||
| --- value moved here
|
| --- value moved here
|
||||||
LL | let b = u.y;
|
LL | let b = u.y;
|
||||||
| ^^^ value used here after move
|
| ^^^ value used here after move
|
||||||
|
|
|
||||||
|
note: if `U` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/union-borrow-move-parent-sibling.rs:43:1
|
||||||
|
|
|
||||||
|
LL | union U {
|
||||||
|
| ^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | let a = u.x;
|
||||||
|
| --- you could clone this value
|
||||||
|
|
||||||
error[E0502]: cannot borrow `u` (via `u.y`) as immutable because it is also borrowed as mutable (via `u.x`)
|
error[E0502]: cannot borrow `u` (via `u.y`) as immutable because it is also borrowed as mutable (via `u.x`)
|
||||||
--> $DIR/union-borrow-move-parent-sibling.rs:67:13
|
--> $DIR/union-borrow-move-parent-sibling.rs:67:13
|
||||||
@@ -73,6 +82,15 @@ LL | let a = u.x;
|
|||||||
| --- value moved here
|
| --- value moved here
|
||||||
LL | let b = u.y;
|
LL | let b = u.y;
|
||||||
| ^^^ value used here after move
|
| ^^^ value used here after move
|
||||||
|
|
|
||||||
|
note: if `U` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/union-borrow-move-parent-sibling.rs:43:1
|
||||||
|
|
|
||||||
|
LL | union U {
|
||||||
|
| ^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | let a = u.x;
|
||||||
|
| --- you could clone this value
|
||||||
|
|
||||||
error[E0502]: cannot borrow `u` (via `u.x`) as immutable because it is also borrowed as mutable (via `u.y`)
|
error[E0502]: cannot borrow `u` (via `u.x`) as immutable because it is also borrowed as mutable (via `u.y`)
|
||||||
--> $DIR/union-borrow-move-parent-sibling.rs:81:13
|
--> $DIR/union-borrow-move-parent-sibling.rs:81:13
|
||||||
|
|||||||
@@ -16,6 +16,15 @@ LL | let binder: unsafe<> NotCopy = wrap_binder!(base);
|
|||||||
| ---- value moved here
|
| ---- value moved here
|
||||||
LL | drop(base);
|
LL | drop(base);
|
||||||
| ^^^^ value used here after move
|
| ^^^^ value used here after move
|
||||||
|
|
|
||||||
|
note: if `NotCopyInner` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/moves.rs:8:1
|
||||||
|
|
|
||||||
|
LL | struct NotCopyInner;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | let binder: unsafe<> NotCopy = wrap_binder!(base);
|
||||||
|
| ---- you could clone this value
|
||||||
|
|
||||||
error[E0382]: use of moved value: `binder`
|
error[E0382]: use of moved value: `binder`
|
||||||
--> $DIR/moves.rs:24:14
|
--> $DIR/moves.rs:24:14
|
||||||
|
|||||||
@@ -17,6 +17,14 @@ LL | fn push(&mut self, n: Box<dyn ToString + 'static>) {
|
|||||||
| ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ this parameter takes ownership of the value
|
| ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ this parameter takes ownership of the value
|
||||||
| |
|
| |
|
||||||
| in this method
|
| in this method
|
||||||
|
note: if `Number` implemented `Clone`, you could clone the value
|
||||||
|
--> $DIR/use-after-move-implicity-coerced-object.rs:3:1
|
||||||
|
|
|
||||||
|
LL | struct Number {
|
||||||
|
| ^^^^^^^^^^^^^ consider implementing `Clone` for this type
|
||||||
|
...
|
||||||
|
LL | l.push(n);
|
||||||
|
| - you could clone this value
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user