-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Unhelpful lifetime error on .clone() refers to &&T, could suggest adding Clone #40699
Comments
Hi - do you need any further information for triage? |
Triage: the error has changed slightly:
|
Current error:
|
After applying the suggestion mentioned above, the output is
Potentially the lint should mention I believe that the direction the suggestions take us is perfectly valid given the available constraints (it makes sense to lead people towards borrowing more than cloning). |
…st `#[derive(Clone)]` CC rust-lang#40699.
The only thing left after #121471 is to mention |
When encountering `<&T as Clone>::clone(x)` because `T: Clone`, suggest `#[derive(Clone)]` CC rust-lang#40699. ``` warning: call to `.clone()` on a reference in this situation does nothing --> $DIR/noop-method-call.rs:23:71 | LL | let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref.clone(); | ^^^^^^^^ | = note: the type `PlainType<u32>` does not implement `Clone`, so calling `clone` on `&PlainType<u32>` copies the reference, which does not do anything and can be removed help: remove this redundant call | LL - let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref.clone(); LL + let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref; | help: if you meant to clone `PlainType<u32>`, implement `Clone` for it | LL + #[derive(Clone)] LL | struct PlainType<T>(T); | ```
Rollup merge of rust-lang#121471 - estebank:lint-clone, r=TaKO8Ki When encountering `<&T as Clone>::clone(x)` because `T: Clone`, suggest `#[derive(Clone)]` CC rust-lang#40699. ``` warning: call to `.clone()` on a reference in this situation does nothing --> $DIR/noop-method-call.rs:23:71 | LL | let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref.clone(); | ^^^^^^^^ | = note: the type `PlainType<u32>` does not implement `Clone`, so calling `clone` on `&PlainType<u32>` copies the reference, which does not do anything and can be removed help: remove this redundant call | LL - let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref.clone(); LL + let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref; | help: if you meant to clone `PlainType<u32>`, implement `Clone` for it | LL + #[derive(Clone)] LL | struct PlainType<T>(T); | ```
First I'll apologise for the extra long comment, but I thought it best to show the steps I went through. Using this rust compiler:
To get a clean build I uncommented the derive clone giving: // Uncomment the derive to make this compile.
#[derive(Clone)]
struct Foo(String);
fn bar(p: &Foo) -> Box<Fn() -> () + '_> {
let p = p.clone();
let f = move || baz(&p);
Box::new(f)
}
fn baz(_: &Foo) {}
pub fn main() {
let foo = Foo("foo".to_string());
let closure = bar(&foo);
closure()
} This now gives an error:
Adding the dyn as specified and allowing dead code gives a clean no messages build. #[allow(dead_code)]
// Uncomment the derive to make this compile.
// #[derive(Clone)]
struct Foo(String);
fn bar(p: &Foo) -> Box<dyn Fn() -> () + '_> {
let p = p.clone();
let f = move || baz(&p);
Box::new(f)
}
fn baz(_: &Foo) {}
pub fn main() {
let foo = Foo("foo".to_string());
let closure = bar(&foo);
closure()
} Compiling this code, finally gives what I think was suggested originally, a suggestion to implement Clone for Foo:
|
Thanks, this is definitely what I was after. Thanks! |
Closing as fixed. Thanks all. |
In code that works with boxed closures (e.g., futures code), it is common to clone an argument so that it can be moved into the closure. If the argument is passed by reference, clone() will clone the value if there is a Clone implementation, otherwise it will pointlessly clone the reference.
If the Clone implementation is not present, rustc reports E0495 quite unhelpfully.
Please could rustc spot this and suggest adding a Clone implementation? I think the signature is an invocation of
clone()
at&T
when the type compatibility being checked is&&T
.Example:
Error message:
The text was updated successfully, but these errors were encountered: