An Option can only be cloned if the inner T implements Clone:
impl<T> Clone for Option<T>
where
T: Clone,
Isn't a None of type T the same as any other None?
Actually, no. The Rust compiler does not even view None as a type. Instead, None is just a variant (subtype) of Option<T>. Try comparing Nones of two different Ts:
let a: Option<String> = None;
let b: Option<u8> = None;
assert_eq!(a, b)
You will see that they are in fact completely unrelated types:
error[E0308]: mismatched types
--> src/main.rs:4:5
|
4 | assert_eq!(a, b)
| ^^^^^^^^^^^^^^^^ expected struct `String`, found `u8`
|
= note: expected enum `Option<String>`
found enum `Option<u8>`
So the Rust compiler actually sees None as Option::<T>::None. This means that if T is not Clone, then Option<T> is not Clone, and therefore Option::<T>::None cannot be Clone.
To make your code compile, you must constrain T to Clone:
struct Foo<T: Clone> {
bar: Vec<Option<T>>,
}
impl <T: Clone> Foo<T> {
fn blank(size: usize) -> Foo<T> {
Foo {
bar: vec![None; size],
}
}
}
Now the compiler knows that T is Clone, and the implementation of Clone for Option<T> (and Option::<T>::None) is fulfilled.