# Layout First off, we need to come up with the struct layout. A Vec has three parts: a pointer to the allocation, the size of the allocation, and the number of elements that have been initialized. Naively, this means we just want this design: ```rust,ignore pub struct Vec { ptr: *mut T, cap: usize, len: usize, } ``` And indeed this would compile. Unfortunately, it would be too strict. The compiler will give us too strict variance. So a `&Vec<&'static str>` couldn't be used where a `&Vec<&'a str>` was expected. See [the chapter on ownership and lifetimes][ownership] for all the details on variance. As we saw in the ownership chapter, the standard library uses `Unique` in place of `*mut T` when it has a raw pointer to an allocation that it owns. Unique is unstable, so we'd like to not use it if possible, though. As a recap, Unique is a wrapper around a raw pointer that declares that: * We are covariant over `T` * We may own a value of type `T` (this is not relevant for our example here, but see [the chapter on PhantomData][phantom-data] on why the real `std::vec::Vec` needs this) * We are Send/Sync if `T` is Send/Sync * Our pointer is never null (so `Option>` is null-pointer-optimized) We can implement all of the above requirements in stable Rust. To do this, instead of using `Unique` we will use [`NonNull`][NonNull], another wrapper around a raw pointer, which gives us two of the above properties, namely it is covariant over `T` and is declared to never be null. By implementing Send/Sync if `T` is, we get the same results as using `Unique`: ```rust use std::ptr::NonNull; pub struct Vec { ptr: NonNull, cap: usize, len: usize, } unsafe impl Send for Vec {} unsafe impl Sync for Vec {} # fn main() {} ``` [ownership]: ../ownership.html [phantom-data]: ../phantom-data.md [NonNull]: ../../std/ptr/struct.NonNull.html