Skip to content

Confusing error message with unimplemented Clone #55121

Closed

Description

@andreytkachenko

Consider this example:

struct Test(u64, u64);
impl Test {
    fn into_tuple(self) -> (u64, u64) {
        (self.0, self.1)
    }
}
fn main() {
    let x = vec![Test(1,1), Test(1,2)];
    
    let _tuples = x.iter().map(|test| test.clone().into_tuple()).collect::<Vec<_>>();
}

struct Test is not implementing Clone trait, but here is the error message:

   Compiling playground v0.0.1 (file:///playground)
error[E0507]: cannot move out of borrowed content
  --> src/main.rs:12:39
   |
12 |     let _tuples = x.iter().map(|test| test.clone().into_tuple()).collect::<Vec<_>>();
   |                                       ^^^^^^^^^^^^ cannot move out of borrowed content

error: aborting due to previous error

Activity

  1. estebank commented on Oct 16, 2018

    @estebank
    Contributor

    Proposed output:

    error[E0507]: cannot move out of borrowed content
      --> src/main.rs:12:39
       |
    1  | struct Test(u64, u64);
       | ---------------------- `Test` doesn't implement `Clone`
    ...
    12 |     let _tuples = x.iter().map(|test| test.clone().into_tuple()).collect::<Vec<_>>();
       |                                       ^^^^^^^^^^^^ cannot move out of borrowed content
       |
       = help: `test` is of type `&Test` and `Test` doesn't implement `Clone`, so you're cloning the borrow
    
    error: aborting due to previous error
    
  2. estebank commented on Jan 22, 2020

    @estebank
    Contributor

    Triage, current output:

    error[E0507]: cannot move out of a shared reference
      --> src/main.rs:10:39
       |
    10 |     let _tuples = x.iter().map(|test| test.clone().into_tuple()).collect::<Vec<_>>();
       |                                       ^^^^^^^^^^^^ move occurs because value has type `Test`, which does not implement the `Copy` trait
    
  3. added
    D-papercutDiagnostics: An error or lint that needs small tweaks.
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Jan 22, 2020
  4. added
    C-enhancementCategory: An issue proposing an enhancement or a PR with one.
    on Apr 12, 2020
  5. estebank commented on Aug 3, 2023

    @estebank
    Contributor

    Current output:

    error[E0507]: cannot move out of a shared reference
      --> src/main.rs:10:39
       |
    10 |     let _tuples = x.iter().map(|test| test.clone().into_tuple()).collect::<Vec<_>>();
       |                                       ^^^^^^^^^^^^^------------
       |                                       |            |
       |                                       |            value moved due to this method call
       |                                       move occurs because value has type `Test`, which does not implement the `Copy` trait
       |
    note: `Test::into_tuple` takes ownership of the receiver `self`, which moves value
      --> src/main.rs:3:19
       |
    3  |     fn into_tuple(self) -> (u64, u64) {
       |                   ^^^^
    

    We should probably suggest #[derive(Copy)] on Test.

  6. estebank commented on Apr 12, 2024

    @estebank
    Contributor

    Output with #122603:

    error[E0507]: cannot move out of a shared reference
      --> f109.rs:10:39
       |
    10 |     let _tuples = x.iter().map(|test| test.clone().into_tuple()).collect::<Vec<_>>();
       |                                       ^^^^^^^^^^^^ ------------ value moved due to this method call
       |                                       |
       |                                       move occurs because value has type `Test`, which does not implement the `Copy` trait
       |
    note: `Test::into_tuple` takes ownership of the receiver `self`, which moves value
      --> f109.rs:3:19
       |
    3  |     fn into_tuple(self) -> (u64, u64) {
       |                   ^^^^
    note: if `Test` implemented `Clone`, you could clone the value
      --> f109.rs:1:1
       |
    1  | struct Test(u64, u64);
       | ^^^^^^^^^^^
    

    We could further explain that the .clone() is on the reference.

  7. estebank commented on May 2, 2024

    @estebank
    Contributor

    Current output:

    error[E0507]: cannot move out of a shared reference
      --> src/main.rs:10:39
       |
    10 |     let _tuples = x.iter().map(|test| test.clone().into_tuple()).collect::<Vec<_>>();
       |                                       ^^^^^^^^^^^^ ------------ value moved due to this method call
       |                                       |
       |                                       move occurs because value has type `Test`, which does not implement the `Copy` trait
       |
    note: `Test::into_tuple` takes ownership of the receiver `self`, which moves value
      --> src/main.rs:3:19
       |
    3  |     fn into_tuple(self) -> (u64, u64) {
       |                   ^^^^
    note: if `Test` implemented `Clone`, you could clone the value
      --> src/main.rs:1:1
       |
    1  | struct Test(u64, u64);
       | ^^^^^^^^^^^ consider implementing `Clone` for this type
    ...
    10 |     let _tuples = x.iter().map(|test| test.clone().into_tuple()).collect::<Vec<_>>();
       |                                       ------------ you could clone this value
    
  8. andreytkachenko commented on Oct 8, 2024

    @andreytkachenko
    ContributorAuthor

    Now it produces better message:

       Compiling playground v0.0.1 (/playground)
    error[E0507]: cannot move out of a shared reference
      --> src/main.rs:10:39
       |
    10 |     let _tuples = x.iter().map(|test| test.clone().into_tuple()).collect::<Vec<_>>();
       |                                       ^^^^^^^^^^^^ ------------ value moved due to this method call
       |                                       |
       |                                       move occurs because value has type `Test`, which does not implement the `Copy` trait
       |
    note: `Test::into_tuple` takes ownership of the receiver `self`, which moves value
      --> src/main.rs:3:19
       |
    3  |     fn into_tuple(self) -> (u64, u64) {
       |                   ^^^^
    note: if `Test` implemented `Clone`, you could clone the value
      --> src/main.rs:1:1
       |
    1  | struct Test(u64, u64);
       | ^^^^^^^^^^^ consider implementing `Clone` for this type
    ...
    10 |     let _tuples = x.iter().map(|test| test.clone().into_tuple()).collect::<Vec<_>>();
       |                                       ------------ you could clone this value
    
    For more information about this error, try `rustc --explain E0507`.
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsC-enhancementCategory: An issue proposing an enhancement or a PR with one.D-papercutDiagnostics: An error or lint that needs small tweaks.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions