Skip to content

Commit 652b793

Browse files
committed
libcollections: Use NonZero in Vec.
1 parent 458475b commit 652b793

File tree

1 file changed

+32
-22
lines changed

1 file changed

+32
-22
lines changed

src/libcollections/vec.rs

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use core::mem;
2626
use core::num::{Int, UnsignedInt};
2727
use core::ops;
2828
use core::ptr;
29+
use core::ptr::NonZero;
2930
use core::raw::Slice as RawSlice;
3031
use core::uint;
3132

@@ -103,7 +104,7 @@ use slice::{CloneSliceAllocPrelude};
103104
#[unsafe_no_drop_flag]
104105
#[stable]
105106
pub struct Vec<T> {
106-
ptr: *mut T,
107+
ptr: NonZero<*mut T>,
107108
len: uint,
108109
cap: uint,
109110
}
@@ -146,7 +147,7 @@ impl<T> Vec<T> {
146147
// non-null value which is fine since we never call deallocate on the ptr
147148
// if cap is 0. The reason for this is because the pointer of a slice
148149
// being NULL would break the null pointer optimization for enums.
149-
Vec { ptr: EMPTY as *mut T, len: 0, cap: 0 }
150+
Vec { ptr: NonZero(EMPTY as *mut T), len: 0, cap: 0 }
150151
}
151152

152153
/// Constructs a new, empty `Vec` with the specified capacity.
@@ -180,15 +181,15 @@ impl<T> Vec<T> {
180181
#[stable]
181182
pub fn with_capacity(capacity: uint) -> Vec<T> {
182183
if mem::size_of::<T>() == 0 {
183-
Vec { ptr: EMPTY as *mut T, len: 0, cap: uint::MAX }
184+
Vec { ptr: NonZero(EMPTY as *mut T), len: 0, cap: uint::MAX }
184185
} else if capacity == 0 {
185186
Vec::new()
186187
} else {
187188
let size = capacity.checked_mul(mem::size_of::<T>())
188189
.expect("capacity overflow");
189190
let ptr = unsafe { allocate(size, mem::min_align_of::<T>()) };
190191
if ptr.is_null() { ::alloc::oom() }
191-
Vec { ptr: ptr as *mut T, len: 0, cap: capacity }
192+
Vec { ptr: NonZero(ptr as *mut T), len: 0, cap: capacity }
192193
}
193194
}
194195

@@ -261,7 +262,7 @@ impl<T> Vec<T> {
261262
#[unstable = "needs finalization"]
262263
pub unsafe fn from_raw_parts(ptr: *mut T, length: uint,
263264
capacity: uint) -> Vec<T> {
264-
Vec { ptr: ptr, len: length, cap: capacity }
265+
Vec { ptr: NonZero(ptr), len: length, cap: capacity }
265266
}
266267

267268
/// Creates a vector by copying the elements from a raw pointer.
@@ -743,22 +744,24 @@ impl<T> Vec<T> {
743744
pub fn shrink_to_fit(&mut self) {
744745
if mem::size_of::<T>() == 0 { return }
745746

747+
let NonZero(ptr) = self.ptr;
746748
if self.len == 0 {
747749
if self.cap != 0 {
748750
unsafe {
749-
dealloc(self.ptr, self.cap)
751+
dealloc(ptr, self.cap)
750752
}
751753
self.cap = 0;
752754
}
753755
} else {
754756
unsafe {
755757
// Overflow check is unnecessary as the vector is already at
756758
// least this large.
757-
self.ptr = reallocate(self.ptr as *mut u8,
758-
self.cap * mem::size_of::<T>(),
759-
self.len * mem::size_of::<T>(),
760-
mem::min_align_of::<T>()) as *mut T;
761-
if self.ptr.is_null() { ::alloc::oom() }
759+
let ptr = reallocate(ptr as *mut u8,
760+
self.cap * mem::size_of::<T>(),
761+
self.len * mem::size_of::<T>(),
762+
mem::min_align_of::<T>()) as *mut T;
763+
if ptr.is_null() { ::alloc::oom() }
764+
self.ptr = NonZero(ptr);
762765
}
763766
self.cap = self.len;
764767
}
@@ -816,9 +819,10 @@ impl<T> Vec<T> {
816819
#[inline]
817820
#[stable]
818821
pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
822+
let NonZero(ptr) = self.ptr;
819823
unsafe {
820824
mem::transmute(RawSlice {
821-
data: self.ptr as *const T,
825+
data: ptr as *const T,
822826
len: self.len,
823827
})
824828
}
@@ -841,9 +845,9 @@ impl<T> Vec<T> {
841845
#[unstable = "matches collection reform specification, waiting for dust to settle"]
842846
pub fn into_iter(self) -> MoveItems<T> {
843847
unsafe {
844-
let ptr = self.ptr;
848+
let NonZero(ptr) = self.ptr;
845849
let cap = self.cap;
846-
let begin = self.ptr as *const T;
850+
let begin = ptr as *const T;
847851
let end = if mem::size_of::<T>() == 0 {
848852
(ptr as uint + self.len()) as *const T
849853
} else {
@@ -1060,14 +1064,16 @@ impl<T> Vec<T> {
10601064
let size = max(old_size, 2 * mem::size_of::<T>()) * 2;
10611065
if old_size > size { panic!("capacity overflow") }
10621066
unsafe {
1063-
self.ptr = alloc_or_realloc(self.ptr, old_size, size);
1064-
if self.ptr.is_null() { ::alloc::oom() }
1067+
let NonZero(ptr) = self.ptr;
1068+
let ptr = alloc_or_realloc(ptr, old_size, size);
1069+
if ptr.is_null() { ::alloc::oom() }
1070+
self.ptr = NonZero(ptr);
10651071
}
10661072
self.cap = max(self.cap, 2) * 2;
10671073
}
10681074

10691075
unsafe {
1070-
let end = (self.ptr as *const T).offset(self.len as int) as *mut T;
1076+
let NonZero(end) = self.ptr.offset(self.len as int);
10711077
ptr::write(&mut *end, value);
10721078
self.len += 1;
10731079
}
@@ -1147,8 +1153,10 @@ impl<T> Vec<T> {
11471153
let size = capacity.checked_mul(mem::size_of::<T>())
11481154
.expect("capacity overflow");
11491155
unsafe {
1150-
self.ptr = alloc_or_realloc(self.ptr, self.cap * mem::size_of::<T>(), size);
1151-
if self.ptr.is_null() { ::alloc::oom() }
1156+
let NonZero(ptr) = self.ptr;
1157+
let ptr = alloc_or_realloc(ptr, self.cap * mem::size_of::<T>(), size);
1158+
if ptr.is_null() { ::alloc::oom() }
1159+
self.ptr = NonZero(ptr);
11521160
}
11531161
self.cap = capacity;
11541162
}
@@ -1267,9 +1275,10 @@ impl<T> AsSlice<T> for Vec<T> {
12671275
#[inline]
12681276
#[stable]
12691277
fn as_slice<'a>(&'a self) -> &'a [T] {
1278+
let NonZero(ptr) = self.ptr;
12701279
unsafe {
12711280
mem::transmute(RawSlice {
1272-
data: self.ptr as *const T,
1281+
data: ptr as *const T,
12731282
len: self.len
12741283
})
12751284
}
@@ -1296,7 +1305,8 @@ impl<T> Drop for Vec<T> {
12961305
for x in self.iter() {
12971306
ptr::read(x);
12981307
}
1299-
dealloc(self.ptr, self.cap)
1308+
let NonZero(ptr) = self.ptr;
1309+
dealloc(ptr, self.cap)
13001310
}
13011311
}
13021312
}
@@ -1332,7 +1342,7 @@ impl<T> MoveItems<T> {
13321342
for _x in self { }
13331343
let MoveItems { allocation, cap, ptr: _ptr, end: _end } = self;
13341344
mem::forget(self);
1335-
Vec { ptr: allocation, cap: cap, len: 0 }
1345+
Vec { ptr: NonZero(allocation), cap: cap, len: 0 }
13361346
}
13371347
}
13381348

0 commit comments

Comments
 (0)