diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index a284ef402575..6e2dc95cfd6e 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -75,12 +75,10 @@ impl Vec { /// ``` #[inline] pub fn new() -> Vec { - // If we have a 0-sized vector, then the base pointer should not be NULL - // because an iterator over the slice will attempt to yield the base - // pointer as the first element in the vector, but this will end up - // being Some(NULL) which is optimized to None. So instead we set ptr - // to some arbitrary non-null value which is fine since we never call - // deallocate on the ptr if cap is 0. + // We want ptr to never be NULL so instead we set it to some arbitrary + // non-null value which is fine since we never call deallocate on the ptr + // if cap is 0. The reason for this is because the pointer of a slice + // being NULL would break the null pointer optimization for enums. Vec { len: 0, cap: 0, ptr: &PTR_MARKER as *const _ as *mut T } } diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 0178c0318b81..8197a7c2dcbe 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -884,17 +884,20 @@ macro_rules! iterator { if self.ptr == self.end { None } else { - let old = self.ptr; - self.ptr = if mem::size_of::() == 0 { + if mem::size_of::() == 0 { // purposefully don't use 'ptr.offset' because for // vectors with 0-size elements this would return the // same pointer. - transmute(self.ptr as uint + 1) - } else { - self.ptr.offset(1) - }; + self.ptr = transmute(self.ptr as uint + 1); - Some(transmute(old)) + // Use a non-null pointer value + Some(transmute(1u)) + } else { + let old = self.ptr; + self.ptr = self.ptr.offset(1); + + Some(transmute(old)) + } } } } @@ -916,13 +919,17 @@ macro_rules! iterator { if self.end == self.ptr { None } else { - self.end = if mem::size_of::() == 0 { + if mem::size_of::() == 0 { // See above for why 'ptr.offset' isn't used - transmute(self.end as uint - 1) + self.end = transmute(self.end as uint - 1); + + // Use a non-null pointer value + Some(transmute(1u)) } else { - self.end.offset(-1) - }; - Some(transmute(self.end)) + self.end = self.end.offset(-1); + + Some(transmute(self.end)) + } } } } @@ -956,7 +963,12 @@ impl<'a, T> RandomAccessIterator<&'a T> for Items<'a, T> { fn idx(&mut self, index: uint) -> Option<&'a T> { unsafe { if index < self.indexable() { - transmute(self.ptr.offset(index as int)) + if mem::size_of::() == 0 { + // Use a non-null pointer value + Some(transmute(1u)) + } else { + Some(transmute(self.ptr.offset(index as int))) + } } else { None }