-
Notifications
You must be signed in to change notification settings - Fork 13.9k
Clone
suggestions
#95115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clone
suggestions
#95115
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,10 @@ LL | touch(&x); | |
| ^^ value borrowed here after partial move | ||
| | ||
= note: partial move occurs because `x.f` has type `String`, which does not implement the `Copy` trait | ||
help: consider cloning `x.f` | ||
| | ||
LL | Foo {f.clone()} => {} | ||
| ++++++++ | ||
Comment on lines
+11
to
+14
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems to be an incorrect suggestion. We'll need to check that we're not in a pattern, we can only call function in expressions. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, but I couldn't figure a way to check :') |
||
|
||
error: aborting due to previous error | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// run-rustfix | ||
#![allow(dead_code)] | ||
|
||
// `Rc` is not ever `Copy`, we should not suggest adding `T: Copy` constraint. | ||
// But should suggest adding `.clone()`. | ||
fn move_rc<T>(t: std::rc::Rc<T>) { | ||
[t.clone(), t]; //~ use of moved value: `t` | ||
} | ||
|
||
// Even though `T` could be `Copy` it's already `Clone` | ||
// so don't suggest adding `T: Copy` constraint, | ||
// instead suggest adding `.clone()`. | ||
fn move_clone_already<T: Clone>(t: T) { | ||
[t.clone(), t]; //~ use of moved value: `t` | ||
} | ||
|
||
// Same as `Rc` | ||
fn move_clone_only<T: Clone>(t: (T, String)) { | ||
[t.clone(), t]; //~ use of moved value: `t` | ||
} | ||
|
||
// loop | ||
fn move_in_a_loop<T: Clone>(t: T) { | ||
loop { | ||
if true { | ||
drop(t.clone()); //~ use of moved value: `t` | ||
} else { | ||
drop(t.clone()); | ||
} | ||
} | ||
} | ||
|
||
fn main() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,33 @@ | ||
// `Rc` is not ever `Copy`, we should not suggest adding `T: Copy` constraint | ||
fn duplicate_rc<T>(t: std::rc::Rc<T>) -> (std::rc::Rc<T>, std::rc::Rc<T>) { | ||
(t, t) //~ use of moved value: `t` | ||
// run-rustfix | ||
#![allow(dead_code)] | ||
|
||
// `Rc` is not ever `Copy`, we should not suggest adding `T: Copy` constraint. | ||
// But should suggest adding `.clone()`. | ||
fn move_rc<T>(t: std::rc::Rc<T>) { | ||
[t, t]; //~ use of moved value: `t` | ||
} | ||
|
||
// Even though `T` could be `Copy` it's already `Clone` | ||
// so don't suggest adding `T: Copy` constraint, | ||
// instead suggest adding `.clone()`. | ||
fn move_clone_already<T: Clone>(t: T) { | ||
[t, t]; //~ use of moved value: `t` | ||
} | ||
|
||
// Same as `Rc` | ||
fn move_clone_only<T>(t: (T, String)) { | ||
[t, t]; //~ use of moved value: `t` | ||
} | ||
|
||
// loop | ||
fn move_in_a_loop<T: Clone>(t: T) { | ||
loop { | ||
if true { | ||
drop(t); //~ use of moved value: `t` | ||
} else { | ||
drop(t); | ||
} | ||
} | ||
} | ||
|
||
fn main() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,71 @@ | ||
error[E0382]: use of moved value: `t` | ||
--> $DIR/use_of_moved_value_clone_suggestions.rs:3:9 | ||
--> $DIR/use_of_moved_value_clone_suggestions.rs:7:9 | ||
| | ||
LL | fn duplicate_rc<T>(t: std::rc::Rc<T>) -> (std::rc::Rc<T>, std::rc::Rc<T>) { | ||
| - move occurs because `t` has type `Rc<T>`, which does not implement the `Copy` trait | ||
LL | (t, t) | ||
LL | fn move_rc<T>(t: std::rc::Rc<T>) { | ||
| - move occurs because `t` has type `Rc<T>`, which does not implement the `Copy` trait | ||
LL | [t, t]; | ||
| - ^ value used here after move | ||
| | | ||
| value moved here | ||
| | ||
help: consider cloning `t` | ||
| | ||
LL | [t.clone(), t]; | ||
| ++++++++ | ||
|
||
error[E0382]: use of moved value: `t` | ||
--> $DIR/use_of_moved_value_clone_suggestions.rs:14:9 | ||
| | ||
LL | fn move_clone_already<T: Clone>(t: T) { | ||
| - move occurs because `t` has type `T`, which does not implement the `Copy` trait | ||
LL | [t, t]; | ||
| - ^ value used here after move | ||
| | | ||
| value moved here | ||
| | ||
help: consider cloning `t` | ||
| | ||
LL | [t.clone(), t]; | ||
| ++++++++ | ||
|
||
error[E0382]: use of moved value: `t` | ||
--> $DIR/use_of_moved_value_clone_suggestions.rs:19:9 | ||
| | ||
LL | fn move_clone_only<T>(t: (T, String)) { | ||
| - move occurs because `t` has type `(T, String)`, which does not implement the `Copy` trait | ||
LL | [t, t]; | ||
| - ^ value used here after move | ||
| | | ||
| value moved here | ||
| | ||
help: consider restricting type parameter `T` | ||
| | ||
LL | fn move_clone_only<T: Clone>(t: (T, String)) { | ||
| +++++++ | ||
help: ...and cloning `t` | ||
| | ||
LL | [t.clone(), t]; | ||
| ++++++++ | ||
|
||
|
||
error[E0382]: use of moved value: `t` | ||
--> $DIR/use_of_moved_value_clone_suggestions.rs:26:18 | ||
| | ||
LL | fn move_in_a_loop<T: Clone>(t: T) { | ||
| - move occurs because `t` has type `T`, which does not implement the `Copy` trait | ||
... | ||
LL | drop(t); | ||
| ^ value moved here, in previous iteration of loop | ||
LL | } else { | ||
LL | drop(t); | ||
| - value moved here, in previous iteration of loop | ||
| | ||
help: consider cloning `t` | ||
| | ||
LL ~ drop(t.clone()); | ||
LL | } else { | ||
LL ~ drop(t.clone()); | ||
| | ||
|
||
error: aborting due to previous error | ||
error: aborting due to 4 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0382`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// Bad `.clone()` suggestions | ||
|
||
struct S<A> { | ||
t: A, | ||
} | ||
|
||
fn struct_field_shortcut_move<T: Clone>(t: T) { | ||
S { t }; | ||
t; //~ use of moved value: `t` | ||
} | ||
|
||
fn closure_clone_will_not_help<T: Clone>(t: T) { | ||
(move || { | ||
t; | ||
})(); | ||
t; //~ use of moved value: `t` | ||
} | ||
|
||
#[derive(Clone)] | ||
struct CloneOnly; | ||
|
||
fn update_syntax<T: Clone>(s: S<T>) { | ||
S { ..s }; | ||
S { ..s }; //~ use of moved value: `s.t` | ||
} | ||
|
||
fn main() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
error[E0382]: use of moved value: `t` | ||
--> $DIR/use_of_moved_value_clone_suggestions_bad.rs:9:5 | ||
| | ||
LL | fn struct_field_shortcut_move<T: Clone>(t: T) { | ||
| - move occurs because `t` has type `T`, which does not implement the `Copy` trait | ||
LL | S { t }; | ||
| - value moved here | ||
LL | t; | ||
| ^ value used here after move | ||
| | ||
help: consider cloning `t` | ||
| | ||
LL | S { t.clone() }; | ||
| ++++++++ | ||
|
||
error[E0382]: use of moved value: `t` | ||
--> $DIR/use_of_moved_value_clone_suggestions_bad.rs:16:5 | ||
| | ||
LL | fn closure_clone_will_not_help<T: Clone>(t: T) { | ||
| - move occurs because `t` has type `T`, which does not implement the `Copy` trait | ||
LL | (move || { | ||
| ------- value moved into closure here | ||
LL | t; | ||
| - variable moved due to use in closure | ||
LL | })(); | ||
LL | t; | ||
| ^ value used here after move | ||
| | ||
help: consider cloning `t` | ||
| | ||
LL | t.clone(); | ||
| ++++++++ | ||
|
||
error[E0382]: use of moved value: `s.t` | ||
--> $DIR/use_of_moved_value_clone_suggestions_bad.rs:24:5 | ||
| | ||
LL | S { ..s }; | ||
| --------- value moved here | ||
LL | S { ..s }; | ||
| ^^^^^^^^^ value used here after move | ||
| | ||
= note: move occurs because `s.t` has type `T`, which does not implement the `Copy` trait | ||
help: consider cloning `s.t` | ||
| | ||
LL | S { ..s }.clone(); | ||
| ++++++++ | ||
|
||
error: aborting due to 3 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0382`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// No suggestions? :( | ||
|
||
// In the future, we may want to suggest deriving `Clone, Copy` for `No` (and then adding `T: Copy`) | ||
struct No; | ||
fn move_non_clone_non_copy<T>(t: (T, No)) { | ||
[t, t]; //~ use of moved value: `t` | ||
} | ||
|
||
fn main() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
error[E0382]: use of moved value: `t` | ||
--> $DIR/use_of_moved_value_no_suggestions.rs:6:9 | ||
| | ||
LL | fn move_non_clone_non_copy<T>(t: (T, No)) { | ||
| - move occurs because `t` has type `(T, No)`, which does not implement the `Copy` trait | ||
LL | [t, t]; | ||
| - ^ value used here after move | ||
| | | ||
| value moved here | ||
|
||
error: aborting due to previous error | ||
|
||
For more information about this error, try `rustc --explain E0382`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a method, I think called
expect_lang_item
or similar (don't have the editor open right now to find it) that does thatunwrap
for you in a non-ICEy way.