Skip to content

#[derive(Clone, Copy)] doesn't work #108894

Open
@vporton

Description

@vporton

I tried this code:

use std::marker::PhantomData;

#[derive(Clone, Copy)]
pub struct TypedAddress<T>{
    inner: u64,
    phantom: PhantomData<T>,
}

pub trait Memory {
    fn write_value<T>(&self, offset: TypedAddress<T>, value: &T);
    fn return_value<T>(&self, offset: TypedAddress<T>) -> T;
    fn update_value<T, F>(&self, offset: TypedAddress<T>, update: F)
        where F: FnOnce(T) -> T
    {
        let old = self.return_value(offset);
        let new = update(old);
        self.write_value(offset, &new);
    }
}

I expected to see it compiled.

Instead, this happened:

error[E0382]: use of moved value: `offset`
  --> src/test.rs:17:26
   |
12 |     fn update_value<T, F>(&self, offset: TypedAddress<T>, update: F)
   |                                  ------ move occurs because `offset` has type `test::TypedAddress<T>`, which does not implement the `Copy` trait
...
15 |         let old = self.return_value(offset);
   |                                     ------ value moved here
16 |         let new = update(old);
17 |         self.write_value(offset, &new);
   |                          ^^^^^^ value used here after move
   |
help: consider further restricting type parameter `T`
   |
13 |         where F: FnOnce(T) -> T, T: Copy
   |                                +++++++++

error[E0382]: use of moved value: `offset`
  --> src/ic.rs:53:26
   |
49 |     fn update_value<T, F>(&self, offset: TypedAddress<T>, update: F)
   |                                  ------ move occurs because `offset` has type `ic::TypedAddress<T>`, which does not implement the `Copy` trait
...
52 |         let old = self.return_value(offset);
   |                                     ------ value moved here
53 |         self.write_value(offset, &update(old));
   |                          ^^^^^^ value used here after move
   |
help: consider further restricting type parameter `T`
   |
50 |         where F: FnOnce(T) -> T, T: Copy
   |                                +++++++++

For more information about this error, try `rustc --explain E0382`.

Meta

rustc --version --verbose:

rustc 1.67.1 (d5a82bbd2 2023-02-07)
binary: rustc
commit-hash: d5a82bbd26e1ad8b7401f6a718a9c57c96905483
commit-date: 2023-02-07
host: x86_64-unknown-linux-gnu
release: 1.67.1
LLVM version: 15.0.6
$ rustc --version --verbose
rustc 1.69.0-nightly (9aa5c24b7 2023-02-17)
binary: rustc
commit-hash: 9aa5c24b7d763fb98d998819571128ff2eb8a3ca
commit-date: 2023-02-17
host: x86_64-unknown-linux-gnu
release: 1.69.0-nightly
LLVM version: 15.0.7

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)A-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`D-newcomer-roadblockDiagnostics: Confusing error or lint; hard to understand for new users.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