Search code examples
genericsrustclone

Why can't None be cloned for a generic Option<T> when T doesn't implement Clone?


Given a struct with a generic Option<T> where T might not implement Clone why can't None be cloned? Isn't a None of type T the same as any other None? For example:

struct Foo<T> {
    bar: Vec<Option<T>>,
}

impl <T> Foo<T> {
    fn blank(size: usize) -> Foo<T> {
        Foo {
            bar: vec![None; size],
        }
    }
}

Solution

  • Isn't a None of type T the same as any other None?

    Definitely not! Unlike reference-based languages where null is typically internally represented as a null pointer (pointer whose address is 0), Rust's Option<T> introduces no indirection and stores T inline when the option is Some. Since all enum variants have the type of the enum and therefore the same size, the None variant must still occupy at least as much space as T.

    Having said that, it is technically true that the None value could be cloned without T being Clone simply because the None variant of the enum doesn't contain the T, it only stores the discriminator and reserves space that could contain T if the variant were to change to Some. But since Rust enum variants are not separate types, a trait bound defined for the enum must cover all variants.

    See other answers more detailed explanations and instructions how to create a vector of None values of a non-cloneable Option.