Skip to content

Commit 25de80a

Browse files
committed
Remove common usage pattern from AllocRef
1 parent 4d1241f commit 25de80a

File tree

3 files changed

+9
-223
lines changed

3 files changed

+9
-223
lines changed

src/liballoc/raw_vec.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ impl<T, A: AllocRef> RawVec<T, A> {
280280
// 0, getting to here necessarily means the `RawVec` is overfull.
281281
assert!(elem_size != 0, "capacity overflow");
282282

283-
let (new_cap, uniq) = match self.current_layout() {
283+
let (new_cap, ptr) = match self.current_layout() {
284284
Some(cur) => {
285285
// Since we guarantee that we never allocate more than
286286
// `isize::MAX` bytes, `elem_size * self.cap <= isize::MAX` as
@@ -297,7 +297,7 @@ impl<T, A: AllocRef> RawVec<T, A> {
297297
alloc_guard(new_size).unwrap_or_else(|_| capacity_overflow());
298298
let ptr_res = self.a.realloc(NonNull::from(self.ptr).cast(), cur, new_size);
299299
match ptr_res {
300-
Ok(ptr) => (new_cap, ptr.cast().into()),
300+
Ok(ptr) => (new_cap, ptr),
301301
Err(_) => handle_alloc_error(Layout::from_size_align_unchecked(
302302
new_size,
303303
cur.align(),
@@ -308,13 +308,14 @@ impl<T, A: AllocRef> RawVec<T, A> {
308308
// Skip to 4 because tiny `Vec`'s are dumb; but not if that
309309
// would cause overflow.
310310
let new_cap = if elem_size > (!0) / 8 { 1 } else { 4 };
311-
match self.a.alloc_array::<T>(new_cap) {
312-
Ok(ptr) => (new_cap, ptr.into()),
313-
Err(_) => handle_alloc_error(Layout::array::<T>(new_cap).unwrap()),
311+
let layout = Layout::array::<T>(new_cap).unwrap();
312+
match self.a.alloc(layout) {
313+
Ok(ptr) => (new_cap, ptr),
314+
Err(_) => handle_alloc_error(layout),
314315
}
315316
}
316317
};
317-
self.ptr = uniq;
318+
self.ptr = ptr.cast().into();
318319
self.cap = new_cap;
319320
}
320321
}

src/libcore/alloc.rs

+2-199
Original file line numberDiff line numberDiff line change
@@ -593,9 +593,8 @@ pub unsafe trait GlobalAlloc {
593593
///
594594
/// * the starting address for that memory block was previously
595595
/// returned by a previous call to an allocation method (`alloc`,
596-
/// `alloc_zeroed`, `alloc_excess`, `alloc_one`, `alloc_array`) or
597-
/// reallocation method (`realloc`, `realloc_excess`, or
598-
/// `realloc_array`), and
596+
/// `alloc_zeroed`, `alloc_excess`) or reallocation method
597+
/// (`realloc`, `realloc_excess`), and
599598
///
600599
/// * the memory block has not been subsequently deallocated, where
601600
/// blocks are deallocated either by being passed to a deallocation
@@ -606,11 +605,6 @@ pub unsafe trait GlobalAlloc {
606605
/// methods in the `AllocRef` trait state that allocation requests
607606
/// must be non-zero size, or else undefined behavior can result.
608607
///
609-
/// * However, some higher-level allocation methods (`alloc_one`,
610-
/// `alloc_array`) are well-defined on zero-sized types and can
611-
/// optionally support them: it is left up to the implementor
612-
/// whether to return `Err`, or to return `Ok` with some pointer.
613-
///
614608
/// * If an `AllocRef` implementation chooses to return `Ok` in this
615609
/// case (i.e., the pointer denotes a zero-sized inaccessible block)
616610
/// then that returned pointer must be considered "currently
@@ -1035,195 +1029,4 @@ pub unsafe trait AllocRef {
10351029
// new_layout.size() <= layout.size() [required by this method]
10361030
if l <= new_size { Ok(()) } else { Err(CannotReallocInPlace) }
10371031
}
1038-
1039-
// == COMMON USAGE PATTERNS ==
1040-
// alloc_one, dealloc_one, alloc_array, realloc_array. dealloc_array
1041-
1042-
/// Allocates a block suitable for holding an instance of `T`.
1043-
///
1044-
/// Captures a common usage pattern for allocators.
1045-
///
1046-
/// The returned block is suitable for passing to the
1047-
/// `realloc`/`dealloc` methods of this allocator.
1048-
///
1049-
/// Note to implementors: If this returns `Ok(ptr)`, then `ptr`
1050-
/// must be considered "currently allocated" and must be
1051-
/// acceptable input to methods such as `realloc` or `dealloc`,
1052-
/// *even if* `T` is a zero-sized type. In other words, if your
1053-
/// `AllocRef` implementation overrides this method in a manner
1054-
/// that can return a zero-sized `ptr`, then all reallocation and
1055-
/// deallocation methods need to be similarly overridden to accept
1056-
/// such values as input.
1057-
///
1058-
/// # Errors
1059-
///
1060-
/// Returning `Err` indicates that either memory is exhausted or
1061-
/// `T` does not meet allocator's size or alignment constraints.
1062-
///
1063-
/// For zero-sized `T`, may return either of `Ok` or `Err`, but
1064-
/// will *not* yield undefined behavior.
1065-
///
1066-
/// Clients wishing to abort computation in response to an
1067-
/// allocation error are encouraged to call the [`handle_alloc_error`] function,
1068-
/// rather than directly invoking `panic!` or similar.
1069-
///
1070-
/// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
1071-
fn alloc_one<T>(&mut self) -> Result<NonNull<T>, AllocErr>
1072-
where
1073-
Self: Sized,
1074-
{
1075-
let k = Layout::new::<T>();
1076-
if k.size() > 0 { unsafe { self.alloc(k).map(|p| p.cast()) } } else { Err(AllocErr) }
1077-
}
1078-
1079-
/// Deallocates a block suitable for holding an instance of `T`.
1080-
///
1081-
/// The given block must have been produced by this allocator,
1082-
/// and must be suitable for storing a `T` (in terms of alignment
1083-
/// as well as minimum and maximum size); otherwise yields
1084-
/// undefined behavior.
1085-
///
1086-
/// Captures a common usage pattern for allocators.
1087-
///
1088-
/// # Safety
1089-
///
1090-
/// This function is unsafe because undefined behavior can result
1091-
/// if the caller does not ensure both:
1092-
///
1093-
/// * `ptr` must denote a block of memory currently allocated via this allocator
1094-
///
1095-
/// * the layout of `T` must *fit* that block of memory.
1096-
unsafe fn dealloc_one<T>(&mut self, ptr: NonNull<T>)
1097-
where
1098-
Self: Sized,
1099-
{
1100-
let k = Layout::new::<T>();
1101-
if k.size() > 0 {
1102-
self.dealloc(ptr.cast(), k);
1103-
}
1104-
}
1105-
1106-
/// Allocates a block suitable for holding `n` instances of `T`.
1107-
///
1108-
/// Captures a common usage pattern for allocators.
1109-
///
1110-
/// The returned block is suitable for passing to the
1111-
/// `realloc`/`dealloc` methods of this allocator.
1112-
///
1113-
/// Note to implementors: If this returns `Ok(ptr)`, then `ptr`
1114-
/// must be considered "currently allocated" and must be
1115-
/// acceptable input to methods such as `realloc` or `dealloc`,
1116-
/// *even if* `T` is a zero-sized type. In other words, if your
1117-
/// `AllocRef` implementation overrides this method in a manner
1118-
/// that can return a zero-sized `ptr`, then all reallocation and
1119-
/// deallocation methods need to be similarly overridden to accept
1120-
/// such values as input.
1121-
///
1122-
/// # Errors
1123-
///
1124-
/// Returning `Err` indicates that either memory is exhausted or
1125-
/// `[T; n]` does not meet allocator's size or alignment
1126-
/// constraints.
1127-
///
1128-
/// For zero-sized `T` or `n == 0`, may return either of `Ok` or
1129-
/// `Err`, but will *not* yield undefined behavior.
1130-
///
1131-
/// Always returns `Err` on arithmetic overflow.
1132-
///
1133-
/// Clients wishing to abort computation in response to an
1134-
/// allocation error are encouraged to call the [`handle_alloc_error`] function,
1135-
/// rather than directly invoking `panic!` or similar.
1136-
///
1137-
/// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
1138-
fn alloc_array<T>(&mut self, n: usize) -> Result<NonNull<T>, AllocErr>
1139-
where
1140-
Self: Sized,
1141-
{
1142-
match Layout::array::<T>(n) {
1143-
Ok(layout) if layout.size() > 0 => unsafe { self.alloc(layout).map(|p| p.cast()) },
1144-
_ => Err(AllocErr),
1145-
}
1146-
}
1147-
1148-
/// Reallocates a block previously suitable for holding `n_old`
1149-
/// instances of `T`, returning a block suitable for holding
1150-
/// `n_new` instances of `T`.
1151-
///
1152-
/// Captures a common usage pattern for allocators.
1153-
///
1154-
/// The returned block is suitable for passing to the
1155-
/// `realloc`/`dealloc` methods of this allocator.
1156-
///
1157-
/// # Safety
1158-
///
1159-
/// This function is unsafe because undefined behavior can result
1160-
/// if the caller does not ensure all of the following:
1161-
///
1162-
/// * `ptr` must be currently allocated via this allocator,
1163-
///
1164-
/// * the layout of `[T; n_old]` must *fit* that block of memory.
1165-
///
1166-
/// # Errors
1167-
///
1168-
/// Returning `Err` indicates that either memory is exhausted or
1169-
/// `[T; n_new]` does not meet allocator's size or alignment
1170-
/// constraints.
1171-
///
1172-
/// For zero-sized `T` or `n_new == 0`, may return either of `Ok` or
1173-
/// `Err`, but will *not* yield undefined behavior.
1174-
///
1175-
/// Always returns `Err` on arithmetic overflow.
1176-
///
1177-
/// Clients wishing to abort computation in response to a
1178-
/// reallocation error are encouraged to call the [`handle_alloc_error`] function,
1179-
/// rather than directly invoking `panic!` or similar.
1180-
///
1181-
/// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
1182-
unsafe fn realloc_array<T>(
1183-
&mut self,
1184-
ptr: NonNull<T>,
1185-
n_old: usize,
1186-
n_new: usize,
1187-
) -> Result<NonNull<T>, AllocErr>
1188-
where
1189-
Self: Sized,
1190-
{
1191-
match (Layout::array::<T>(n_old), Layout::array::<T>(n_new)) {
1192-
(Ok(k_old), Ok(k_new)) if k_old.size() > 0 && k_new.size() > 0 => {
1193-
debug_assert!(k_old.align() == k_new.align());
1194-
self.realloc(ptr.cast(), k_old, k_new.size()).map(NonNull::cast)
1195-
}
1196-
_ => Err(AllocErr),
1197-
}
1198-
}
1199-
1200-
/// Deallocates a block suitable for holding `n` instances of `T`.
1201-
///
1202-
/// Captures a common usage pattern for allocators.
1203-
///
1204-
/// # Safety
1205-
///
1206-
/// This function is unsafe because undefined behavior can result
1207-
/// if the caller does not ensure both:
1208-
///
1209-
/// * `ptr` must denote a block of memory currently allocated via this allocator
1210-
///
1211-
/// * the layout of `[T; n]` must *fit* that block of memory.
1212-
///
1213-
/// # Errors
1214-
///
1215-
/// Returning `Err` indicates that either `[T; n]` or the given
1216-
/// memory block does not meet allocator's size or alignment
1217-
/// constraints.
1218-
///
1219-
/// Always returns `Err` on arithmetic overflow.
1220-
unsafe fn dealloc_array<T>(&mut self, ptr: NonNull<T>, n: usize) -> Result<(), AllocErr>
1221-
where
1222-
Self: Sized,
1223-
{
1224-
match Layout::array::<T>(n) {
1225-
Ok(k) if k.size() > 0 => Ok(self.dealloc(ptr.cast(), k)),
1226-
_ => Err(AllocErr),
1227-
}
1228-
}
12291032
}

src/test/ui/allocator-alloc-one.rs

-18
This file was deleted.

0 commit comments

Comments
 (0)