@@ -94,9 +94,9 @@ impl Layout {
94
94
/// must not overflow (i.e. the rounded value must be less than
95
95
/// `usize::MAX`).
96
96
#[ inline]
97
- pub fn from_size_align ( size : usize , align : usize ) -> Option < Layout > {
97
+ pub fn from_size_align ( size : usize , align : usize ) -> Result < Self , LayoutErr > {
98
98
if !align. is_power_of_two ( ) {
99
- return None ;
99
+ return Err ( LayoutErr { private : ( ) } ) ;
100
100
}
101
101
102
102
// (power-of-two implies align != 0.)
@@ -114,11 +114,11 @@ impl Layout {
114
114
// Above implies that checking for summation overflow is both
115
115
// necessary and sufficient.
116
116
if size > usize:: MAX - ( align - 1 ) {
117
- return None ;
117
+ return Err ( LayoutErr { private : ( ) } ) ;
118
118
}
119
119
120
120
unsafe {
121
- Some ( Layout :: from_size_align_unchecked ( size, align) )
121
+ Ok ( Layout :: from_size_align_unchecked ( size, align) )
122
122
}
123
123
}
124
124
@@ -130,7 +130,7 @@ impl Layout {
130
130
/// a power-of-two nor `size` aligned to `align` fits within the
131
131
/// address space (i.e. the `Layout::from_size_align` preconditions).
132
132
#[ inline]
133
- pub unsafe fn from_size_align_unchecked ( size : usize , align : usize ) -> Layout {
133
+ pub unsafe fn from_size_align_unchecked ( size : usize , align : usize ) -> Self {
134
134
Layout { size : size, align : align }
135
135
}
136
136
@@ -229,15 +229,17 @@ impl Layout {
229
229
///
230
230
/// On arithmetic overflow, returns `None`.
231
231
#[ inline]
232
- pub fn repeat ( & self , n : usize ) -> Option < ( Self , usize ) > {
233
- let padded_size = self . size . checked_add ( self . padding_needed_for ( self . align ) ) ?;
234
- let alloc_size = padded_size. checked_mul ( n) ?;
232
+ pub fn repeat ( & self , n : usize ) -> Result < ( Self , usize ) , LayoutErr > {
233
+ let padded_size = self . size . checked_add ( self . padding_needed_for ( self . align ) )
234
+ . ok_or ( LayoutErr { private : ( ) } ) ?;
235
+ let alloc_size = padded_size. checked_mul ( n)
236
+ . ok_or ( LayoutErr { private : ( ) } ) ?;
235
237
236
238
// We can assume that `self.align` is a power-of-two.
237
239
// Furthermore, `alloc_size` has already been rounded up
238
240
// to a multiple of `self.align`; therefore, the call to
239
241
// `Layout::from_size_align` below should never panic.
240
- Some ( ( Layout :: from_size_align ( alloc_size, self . align ) . unwrap ( ) , padded_size) )
242
+ Ok ( ( Layout :: from_size_align ( alloc_size, self . align ) . unwrap ( ) , padded_size) )
241
243
}
242
244
243
245
/// Creates a layout describing the record for `self` followed by
@@ -251,17 +253,19 @@ impl Layout {
251
253
/// (assuming that the record itself starts at offset 0).
252
254
///
253
255
/// On arithmetic overflow, returns `None`.
254
- pub fn extend ( & self , next : Self ) -> Option < ( Self , usize ) > {
256
+ pub fn extend ( & self , next : Self ) -> Result < ( Self , usize ) , LayoutErr > {
255
257
let new_align = cmp:: max ( self . align , next. align ) ;
256
258
let realigned = Layout :: from_size_align ( self . size , new_align) ?;
257
259
258
260
let pad = realigned. padding_needed_for ( next. align ) ;
259
261
260
- let offset = self . size . checked_add ( pad) ?;
261
- let new_size = offset. checked_add ( next. size ) ?;
262
+ let offset = self . size . checked_add ( pad)
263
+ . ok_or ( LayoutErr { private : ( ) } ) ?;
264
+ let new_size = offset. checked_add ( next. size )
265
+ . ok_or ( LayoutErr { private : ( ) } ) ?;
262
266
263
267
let layout = Layout :: from_size_align ( new_size, new_align) ?;
264
- Some ( ( layout, offset) )
268
+ Ok ( ( layout, offset) )
265
269
}
266
270
267
271
/// Creates a layout describing the record for `n` instances of
@@ -276,8 +280,8 @@ impl Layout {
276
280
/// aligned.
277
281
///
278
282
/// On arithmetic overflow, returns `None`.
279
- pub fn repeat_packed ( & self , n : usize ) -> Option < Self > {
280
- let size = self . size ( ) . checked_mul ( n) ?;
283
+ pub fn repeat_packed ( & self , n : usize ) -> Result < Self , LayoutErr > {
284
+ let size = self . size ( ) . checked_mul ( n) . ok_or ( LayoutErr { private : ( ) } ) ?;
281
285
Layout :: from_size_align ( size, self . align )
282
286
}
283
287
@@ -296,16 +300,17 @@ impl Layout {
296
300
/// `extend`.)
297
301
///
298
302
/// On arithmetic overflow, returns `None`.
299
- pub fn extend_packed ( & self , next : Self ) -> Option < ( Self , usize ) > {
300
- let new_size = self . size ( ) . checked_add ( next. size ( ) ) ?;
303
+ pub fn extend_packed ( & self , next : Self ) -> Result < ( Self , usize ) , LayoutErr > {
304
+ let new_size = self . size ( ) . checked_add ( next. size ( ) )
305
+ . ok_or ( LayoutErr { private : ( ) } ) ?;
301
306
let layout = Layout :: from_size_align ( new_size, self . align ) ?;
302
- Some ( ( layout, self . size ( ) ) )
307
+ Ok ( ( layout, self . size ( ) ) )
303
308
}
304
309
305
310
/// Creates a layout describing the record for a `[T; n]`.
306
311
///
307
312
/// On arithmetic overflow, returns `None`.
308
- pub fn array < T > ( n : usize ) -> Option < Self > {
313
+ pub fn array < T > ( n : usize ) -> Result < Self , LayoutErr > {
309
314
Layout :: new :: < T > ( )
310
315
. repeat ( n)
311
316
. map ( |( k, offs) | {
@@ -315,6 +320,20 @@ impl Layout {
315
320
}
316
321
}
317
322
323
+ /// The parameters given to `Layout::from_size_align` do not satisfy
324
+ /// its documented constraints.
325
+ #[ derive( Clone , PartialEq , Eq , Debug ) ]
326
+ pub struct LayoutErr {
327
+ private : ( )
328
+ }
329
+
330
+ // (we need this for downstream impl of trait Error)
331
+ impl fmt:: Display for LayoutErr {
332
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
333
+ f. write_str ( "invalid parameters to Layout::from_size_align" )
334
+ }
335
+ }
336
+
318
337
/// The `AllocErr` error specifies whether an allocation failure is
319
338
/// specifically due to resource exhaustion or if it is due to
320
339
/// something wrong when combining the given input arguments with this
@@ -990,7 +1009,7 @@ pub unsafe trait Alloc {
990
1009
where Self : Sized
991
1010
{
992
1011
match Layout :: array :: < T > ( n) {
993
- Some ( ref layout) if layout. size ( ) > 0 => {
1012
+ Ok ( ref layout) if layout. size ( ) > 0 => {
994
1013
unsafe {
995
1014
self . alloc ( layout. clone ( ) )
996
1015
. map ( |p| {
@@ -1041,7 +1060,7 @@ pub unsafe trait Alloc {
1041
1060
where Self : Sized
1042
1061
{
1043
1062
match ( Layout :: array :: < T > ( n_old) , Layout :: array :: < T > ( n_new) , ptr. as_ptr ( ) ) {
1044
- ( Some ( ref k_old) , Some ( ref k_new) , ptr) if k_old. size ( ) > 0 && k_new. size ( ) > 0 => {
1063
+ ( Ok ( ref k_old) , Ok ( ref k_new) , ptr) if k_old. size ( ) > 0 && k_new. size ( ) > 0 => {
1045
1064
self . realloc ( ptr as * mut u8 , k_old. clone ( ) , k_new. clone ( ) )
1046
1065
. map ( |p| NonNull :: new_unchecked ( p as * mut T ) )
1047
1066
}
@@ -1076,7 +1095,7 @@ pub unsafe trait Alloc {
1076
1095
{
1077
1096
let raw_ptr = ptr. as_ptr ( ) as * mut u8 ;
1078
1097
match Layout :: array :: < T > ( n) {
1079
- Some ( ref k) if k. size ( ) > 0 => {
1098
+ Ok ( ref k) if k. size ( ) > 0 => {
1080
1099
Ok ( self . dealloc ( raw_ptr, k. clone ( ) ) )
1081
1100
}
1082
1101
_ => {
0 commit comments