Copy trait and PhantomData: should this really move?

PhantomDatainteracts unexpectedly with Copy:

use std::marker::PhantomData;

#[derive(Copy, Clone)]
pub struct Seconds;

pub struct Meters;

#[derive(Copy, Clone)]
pub struct Val<T> {
    pub v: PhantomData<T>
}

fn main() {
    let v1: Val<Seconds> = Val {v: PhantomData};
    let v2 = v1;
    let v3 = v1;

    let v4: Val<Meters> = Val {v: PhantomData};
    let v5 = v4;
    let v6 = v4;
}

This is not true:

src/main.rs:20:13: 20:15 error: use of moved value: `v4` [E0382]
src/main.rs:20         let v6 = v4;
                           ^~
src/main.rs:19:13: 19:15 note: `v4` moved here because it has type `Val<Meters>`, which is moved by default
src/main.rs:19         let v5 = v4;

I thought getting Copyfor Val<Meters>would give Val<Meters>copy semantics. But, apparently, this is only true where the Valtype parameter Talso implements Copy. I do not understand why.

PhantomDataalways implements Copy, regardless of whether its type parameter has it . And in general, if I PhantomData<Meters>did not implement it Copy, I would expect the compiler to complain about what it could not get Copyfor Val<Meters>. Instead, the compiler happily gets Copyfor Val<Meters>, but it applies the semantics of movement.

Is this behavior intentional? If so, why?

+4
1

, Copy Val<Meters> Val<Meters> .

Copy Val<Meters>, Val<T>, T Copy.

Github , . . , , derive .

, Clone Copy:

impl <T> Clone for Val<T> {
    fn clone(&self) -> Val<T> {
        Val {v: PhantomData}
    }
}

impl <T> Copy for Val<T> {}
+3

All Articles