@@ -26,6 +26,7 @@ use core::mem;
26
26
use core:: num:: { Int , UnsignedInt } ;
27
27
use core:: ops;
28
28
use core:: ptr;
29
+ use core:: ptr:: NonZero ;
29
30
use core:: raw:: Slice as RawSlice ;
30
31
use core:: uint;
31
32
@@ -103,7 +104,7 @@ use slice::{CloneSliceAllocPrelude};
103
104
#[ unsafe_no_drop_flag]
104
105
#[ stable]
105
106
pub struct Vec < T > {
106
- ptr : * mut T ,
107
+ ptr : NonZero < * mut T > ,
107
108
len : uint ,
108
109
cap : uint ,
109
110
}
@@ -146,7 +147,7 @@ impl<T> Vec<T> {
146
147
// non-null value which is fine since we never call deallocate on the ptr
147
148
// if cap is 0. The reason for this is because the pointer of a slice
148
149
// 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 }
150
151
}
151
152
152
153
/// Constructs a new, empty `Vec` with the specified capacity.
@@ -180,15 +181,15 @@ impl<T> Vec<T> {
180
181
#[ stable]
181
182
pub fn with_capacity ( capacity : uint ) -> Vec < T > {
182
183
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 }
184
185
} else if capacity == 0 {
185
186
Vec :: new ( )
186
187
} else {
187
188
let size = capacity. checked_mul ( mem:: size_of :: < T > ( ) )
188
189
. expect ( "capacity overflow" ) ;
189
190
let ptr = unsafe { allocate ( size, mem:: min_align_of :: < T > ( ) ) } ;
190
191
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 }
192
193
}
193
194
}
194
195
@@ -261,7 +262,7 @@ impl<T> Vec<T> {
261
262
#[ unstable = "needs finalization" ]
262
263
pub unsafe fn from_raw_parts ( ptr : * mut T , length : uint ,
263
264
capacity : uint ) -> Vec < T > {
264
- Vec { ptr : ptr, len : length, cap : capacity }
265
+ Vec { ptr : NonZero ( ptr) , len : length, cap : capacity }
265
266
}
266
267
267
268
/// Creates a vector by copying the elements from a raw pointer.
@@ -743,22 +744,24 @@ impl<T> Vec<T> {
743
744
pub fn shrink_to_fit ( & mut self ) {
744
745
if mem:: size_of :: < T > ( ) == 0 { return }
745
746
747
+ let NonZero ( ptr) = self . ptr ;
746
748
if self . len == 0 {
747
749
if self . cap != 0 {
748
750
unsafe {
749
- dealloc ( self . ptr , self . cap )
751
+ dealloc ( ptr, self . cap )
750
752
}
751
753
self . cap = 0 ;
752
754
}
753
755
} else {
754
756
unsafe {
755
757
// Overflow check is unnecessary as the vector is already at
756
758
// 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) ;
762
765
}
763
766
self . cap = self . len ;
764
767
}
@@ -816,9 +819,10 @@ impl<T> Vec<T> {
816
819
#[ inline]
817
820
#[ stable]
818
821
pub fn as_mut_slice < ' a > ( & ' a mut self ) -> & ' a mut [ T ] {
822
+ let NonZero ( ptr) = self . ptr ;
819
823
unsafe {
820
824
mem:: transmute ( RawSlice {
821
- data : self . ptr as * const T ,
825
+ data : ptr as * const T ,
822
826
len : self . len ,
823
827
} )
824
828
}
@@ -841,9 +845,9 @@ impl<T> Vec<T> {
841
845
#[ unstable = "matches collection reform specification, waiting for dust to settle" ]
842
846
pub fn into_iter ( self ) -> MoveItems < T > {
843
847
unsafe {
844
- let ptr = self . ptr ;
848
+ let NonZero ( ptr) = self . ptr ;
845
849
let cap = self . cap ;
846
- let begin = self . ptr as * const T ;
850
+ let begin = ptr as * const T ;
847
851
let end = if mem:: size_of :: < T > ( ) == 0 {
848
852
( ptr as uint + self . len ( ) ) as * const T
849
853
} else {
@@ -1060,14 +1064,16 @@ impl<T> Vec<T> {
1060
1064
let size = max ( old_size, 2 * mem:: size_of :: < T > ( ) ) * 2 ;
1061
1065
if old_size > size { panic ! ( "capacity overflow" ) }
1062
1066
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) ;
1065
1071
}
1066
1072
self . cap = max ( self . cap , 2 ) * 2 ;
1067
1073
}
1068
1074
1069
1075
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 ) ;
1071
1077
ptr:: write ( & mut * end, value) ;
1072
1078
self . len += 1 ;
1073
1079
}
@@ -1147,8 +1153,10 @@ impl<T> Vec<T> {
1147
1153
let size = capacity. checked_mul ( mem:: size_of :: < T > ( ) )
1148
1154
. expect ( "capacity overflow" ) ;
1149
1155
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) ;
1152
1160
}
1153
1161
self . cap = capacity;
1154
1162
}
@@ -1267,9 +1275,10 @@ impl<T> AsSlice<T> for Vec<T> {
1267
1275
#[ inline]
1268
1276
#[ stable]
1269
1277
fn as_slice < ' a > ( & ' a self ) -> & ' a [ T ] {
1278
+ let NonZero ( ptr) = self . ptr ;
1270
1279
unsafe {
1271
1280
mem:: transmute ( RawSlice {
1272
- data : self . ptr as * const T ,
1281
+ data : ptr as * const T ,
1273
1282
len : self . len
1274
1283
} )
1275
1284
}
@@ -1296,7 +1305,8 @@ impl<T> Drop for Vec<T> {
1296
1305
for x in self . iter ( ) {
1297
1306
ptr:: read ( x) ;
1298
1307
}
1299
- dealloc ( self . ptr , self . cap )
1308
+ let NonZero ( ptr) = self . ptr ;
1309
+ dealloc ( ptr, self . cap )
1300
1310
}
1301
1311
}
1302
1312
}
@@ -1332,7 +1342,7 @@ impl<T> MoveItems<T> {
1332
1342
for _x in self { }
1333
1343
let MoveItems { allocation, cap, ptr : _ptr, end : _end } = self ;
1334
1344
mem:: forget ( self ) ;
1335
- Vec { ptr : allocation, cap : cap, len : 0 }
1345
+ Vec { ptr : NonZero ( allocation) , cap : cap, len : 0 }
1336
1346
}
1337
1347
}
1338
1348
0 commit comments