@@ -15,13 +15,10 @@ pub struct Vec<T> {
1515}
1616```
1717
18- And indeed this would compile. Unfortunately, it would be incorrect. First, the
18+ And indeed this would compile. Unfortunately, it would be too strict. The
1919compiler will give us too strict variance. So a ` &Vec<&'static str> `
20- couldn't be used where an ` &Vec<&'a str> ` was expected. More importantly, it
21- will give incorrect ownership information to the drop checker, as it will
22- conservatively assume we don't own any values of type ` T ` . See [ the chapter
23- on ownership and lifetimes] [ ownership ] for all the details on variance and
24- drop check.
20+ couldn't be used where a ` &Vec<&'a str> ` was expected. See [ the chapter
21+ on ownership and lifetimes] [ ownership ] for all the details on variance.
2522
2623As we saw in the ownership chapter, the standard library uses ` Unique<T> ` in place of
2724` *mut T ` when it has a raw pointer to an allocation that it owns. Unique is unstable,
@@ -30,16 +27,16 @@ so we'd like to not use it if possible, though.
3027As a recap, Unique is a wrapper around a raw pointer that declares that:
3128
3229* We are covariant over ` T `
33- * We may own a value of type ` T ` (for drop check)
30+ * We may own a value of type ` T ` (this is not relevant for our example here, but see
31+ [ the chapter on PhantomData] [ phantom-data ] on why the real ` std::vec::Vec<T> ` needs this)
3432* We are Send/Sync if ` T ` is Send/Sync
3533* Our pointer is never null (so ` Option<Vec<T>> ` is null-pointer-optimized)
3634
3735We can implement all of the above requirements in stable Rust. To do this, instead
3836of using ` Unique<T> ` we will use [ ` NonNull<T> ` ] [ NonNull ] , another wrapper around a
3937raw pointer, which gives us two of the above properties, namely it is covariant
40- over ` T ` and is declared to never be null. By adding a ` PhantomData<T> ` (for drop
41- check) and implementing Send/Sync if ` T ` is, we get the same results as using
42- ` Unique<T> ` :
38+ over ` T ` and is declared to never be null. By implementing Send/Sync if ` T ` is,
39+ we get the same results as using ` Unique<T> ` :
4340
4441``` rust
4542use std :: ptr :: NonNull ;
@@ -49,7 +46,6 @@ pub struct Vec<T> {
4946 ptr : NonNull <T >,
5047 cap : usize ,
5148 len : usize ,
52- _marker : PhantomData <T >,
5349}
5450
5551unsafe impl <T : Send > Send for Vec <T > {}
@@ -58,4 +54,5 @@ unsafe impl<T: Sync> Sync for Vec<T> {}
5854```
5955
6056[ ownership ] : ../ownership.html
57+ [ phantom-data ] : ../phantom-data.md
6158[ NonNull ] : ../../std/ptr/struct.NonNull.html
0 commit comments