diff options
| author | Alexander Regueiro <alexreg@me.com> | 2019-09-05 17:15:28 +0100 |
|---|---|---|
| committer | Alexander Regueiro <alexreg@me.com> | 2019-09-06 16:02:25 +0100 |
| commit | b0006dff1041f0eea718ca29607cd6ec372e4e30 (patch) | |
| tree | de6d8a0d438052c300a561078082bb1f2d62c203 /src/liballoc/raw_vec.rs | |
| parent | 1fb3c4ec7ca37d33bd1e68cce669d171c2752615 (diff) | |
| download | rust-b0006dff1041f0eea718ca29607cd6ec372e4e30.tar.gz rust-b0006dff1041f0eea718ca29607cd6ec372e4e30.zip | |
A few cosmetic improvements to code & comments in liballoc and libcore
Diffstat (limited to 'src/liballoc/raw_vec.rs')
| -rw-r--r-- | src/liballoc/raw_vec.rs | 150 |
1 files changed, 74 insertions, 76 deletions
diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index bc8a38f6b3a..f1c5904afe6 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -19,26 +19,26 @@ mod tests; /// involved. This type is excellent for building your own data structures like Vec and VecDeque. /// In particular: /// -/// * Produces Unique::empty() on zero-sized types -/// * Produces Unique::empty() on zero-length allocations -/// * Catches all overflows in capacity computations (promotes them to "capacity overflow" panics) -/// * Guards against 32-bit systems allocating more than isize::MAX bytes -/// * Guards against overflowing your length -/// * Aborts on OOM or calls handle_alloc_error as applicable -/// * Avoids freeing Unique::empty() -/// * Contains a ptr::Unique and thus endows the user with all related benefits +/// * Produces `Unique::empty()` on zero-sized types. +/// * Produces `Unique::empty()` on zero-length allocations. +/// * Catches all overflows in capacity computations (promotes them to "capacity overflow" panics). +/// * Guards against 32-bit systems allocating more than isize::MAX bytes. +/// * Guards against overflowing your length. +/// * Aborts on OOM or calls `handle_alloc_error` as applicable. +/// * Avoids freeing `Unique::empty()`. +/// * Contains a `ptr::Unique` and thus endows the user with all related benefits. /// /// This type does not in anyway inspect the memory that it manages. When dropped it *will* -/// free its memory, but it *won't* try to Drop its contents. It is up to the user of RawVec -/// to handle the actual things *stored* inside of a RawVec. +/// free its memory, but it *won't* try to drop its contents. It is up to the user of `RawVec` +/// to handle the actual things *stored* inside of a `RawVec`. /// -/// Note that a RawVec always forces its capacity to be usize::MAX for zero-sized types. -/// This enables you to use capacity growing logic catch the overflows in your length +/// Note that a `RawVec` always forces its capacity to be `usize::MAX` for zero-sized types. +/// This enables you to use capacity-growing logic catch the overflows in your length /// that might occur with zero-sized types. /// -/// However this means that you need to be careful when round-tripping this type -/// with a `Box<[T]>`: `capacity()` won't yield the len. However `with_capacity`, -/// `shrink_to_fit`, and `from_box` will actually set RawVec's private capacity +/// The above means that you need to be careful when round-tripping this type with a +/// `Box<[T]>`, since `capacity()` won't yield the length. However, `with_capacity`, +/// `shrink_to_fit`, and `from_box` will actually set `RawVec`'s private capacity /// field. This allows zero-sized types to not be special-cased by consumers of /// this type. #[allow(missing_debug_implementations)] @@ -49,14 +49,14 @@ pub struct RawVec<T, A: Alloc = Global> { } impl<T, A: Alloc> RawVec<T, A> { - /// Like `new` but parameterized over the choice of allocator for - /// the returned RawVec. + /// Like `new`, but parameterized over the choice of allocator for + /// the returned `RawVec`. pub const fn new_in(a: A) -> Self { - // !0 is usize::MAX. This branch should be stripped at compile time. - // FIXME(mark-i-m): use this line when `if`s are allowed in `const` + // `!0` is `usize::MAX`. This branch should be stripped at compile time. + // FIXME(mark-i-m): use this line when `if`s are allowed in `const`: //let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 }; - // Unique::empty() doubles as "unallocated" and "zero-sized allocation" + // `Unique::empty()` doubles as "unallocated" and "zero-sized allocation". RawVec { ptr: Unique::empty(), // FIXME(mark-i-m): use `cap` when ifs are allowed in const @@ -65,15 +65,15 @@ impl<T, A: Alloc> RawVec<T, A> { } } - /// Like `with_capacity` but parameterized over the choice of - /// allocator for the returned RawVec. + /// Like `with_capacity`, but parameterized over the choice of + /// allocator for the returned `RawVec`. #[inline] pub fn with_capacity_in(capacity: usize, a: A) -> Self { RawVec::allocate_in(capacity, false, a) } - /// Like `with_capacity_zeroed` but parameterized over the choice - /// of allocator for the returned RawVec. + /// Like `with_capacity_zeroed`, but parameterized over the choice + /// of allocator for the returned `RawVec`. #[inline] pub fn with_capacity_zeroed_in(capacity: usize, a: A) -> Self { RawVec::allocate_in(capacity, true, a) @@ -86,7 +86,7 @@ impl<T, A: Alloc> RawVec<T, A> { let alloc_size = capacity.checked_mul(elem_size).unwrap_or_else(|| capacity_overflow()); alloc_guard(alloc_size).unwrap_or_else(|_| capacity_overflow()); - // handles ZSTs and `capacity = 0` alike + // Handles ZSTs and `capacity == 0` alike. let ptr = if alloc_size == 0 { NonNull::<T>::dangling() } else { @@ -113,20 +113,20 @@ impl<T, A: Alloc> RawVec<T, A> { } impl<T> RawVec<T, Global> { - /// Creates the biggest possible RawVec (on the system heap) - /// without allocating. If T has positive size, then this makes a - /// RawVec with capacity 0. If T has 0 size, then it makes a - /// RawVec with capacity `usize::MAX`. Useful for implementing + /// Creates the biggest possible `RawVec` (on the system heap) + /// without allocating. If `T` has positive size, then this makes a + /// `RawVec` with capacity `0`. If `T` is zero-sized, then it makes a + /// `RawVec` with capacity `usize::MAX`. Useful for implementing /// delayed allocation. pub const fn new() -> Self { Self::new_in(Global) } - /// Creates a RawVec (on the system heap) with exactly the + /// Creates a `RawVec` (on the system heap) with exactly the /// capacity and alignment requirements for a `[T; capacity]`. This is - /// equivalent to calling RawVec::new when `capacity` is 0 or T is + /// equivalent to calling `RawVec::new` when `capacity` is `0` or `T` is /// zero-sized. Note that if `T` is zero-sized this means you will - /// *not* get a RawVec with the requested capacity! + /// *not* get a `RawVec` with the requested capacity. /// /// # Panics /// @@ -136,13 +136,13 @@ impl<T> RawVec<T, Global> { /// /// # Aborts /// - /// Aborts on OOM + /// Aborts on OOM. #[inline] pub fn with_capacity(capacity: usize) -> Self { RawVec::allocate_in(capacity, false, Global) } - /// Like `with_capacity` but guarantees the buffer is zeroed. + /// Like `with_capacity`, but guarantees the buffer is zeroed. #[inline] pub fn with_capacity_zeroed(capacity: usize) -> Self { RawVec::allocate_in(capacity, true, Global) @@ -150,13 +150,13 @@ impl<T> RawVec<T, Global> { } impl<T, A: Alloc> RawVec<T, A> { - /// Reconstitutes a RawVec from a pointer, capacity, and allocator. + /// Reconstitutes a `RawVec` from a pointer, capacity, and allocator. /// /// # Undefined Behavior /// - /// The ptr must be allocated (via the given allocator `a`), and with the given capacity. The - /// capacity cannot exceed `isize::MAX` (only a concern on 32-bit systems). - /// If the ptr and capacity come from a RawVec created via `a`, then this is guaranteed. + /// The `ptr` must be allocated (via the given allocator `a`), and with the given `capacity`. + /// The `capacity` cannot exceed `isize::MAX` (only a concern on 32-bit systems). + /// If the `ptr` and `capacity` come from a `RawVec` created via `a`, then this is guaranteed. pub unsafe fn from_raw_parts_in(ptr: *mut T, capacity: usize, a: A) -> Self { RawVec { ptr: Unique::new_unchecked(ptr), @@ -167,13 +167,13 @@ impl<T, A: Alloc> RawVec<T, A> { } impl<T> RawVec<T, Global> { - /// Reconstitutes a RawVec from a pointer, capacity. + /// Reconstitutes a `RawVec` from a pointer and capacity. /// /// # Undefined Behavior /// - /// The ptr must be allocated (on the system heap), and with the given capacity. The - /// capacity cannot exceed `isize::MAX` (only a concern on 32-bit systems). - /// If the ptr and capacity come from a RawVec, then this is guaranteed. + /// The `ptr` must be allocated (on the system heap), and with the given `capacity`. + /// Th `capacity` cannot exceed `isize::MAX` (only a concern on 32-bit systems). + /// If the `ptr` and `capacity` come from a `RawVec`, then this is guaranteed. pub unsafe fn from_raw_parts(ptr: *mut T, capacity: usize) -> Self { RawVec { ptr: Unique::new_unchecked(ptr), @@ -194,7 +194,7 @@ impl<T> RawVec<T, Global> { impl<T, A: Alloc> RawVec<T, A> { /// Gets a raw pointer to the start of the allocation. Note that this is - /// Unique::empty() if `capacity = 0` or T is zero-sized. In the former case, you must + /// `Unique::empty()` if `capacity == 0` or `T` is zero-sized. In the former case, you must /// be careful. pub fn ptr(&self) -> *mut T { self.ptr.as_ptr() @@ -212,12 +212,12 @@ impl<T, A: Alloc> RawVec<T, A> { } } - /// Returns a shared reference to the allocator backing this RawVec. + /// Returns a shared reference to the allocator backing this `RawVec`. pub fn alloc(&self) -> &A { &self.a } - /// Returns a mutable reference to the allocator backing this RawVec. + /// Returns a mutable reference to the allocator backing this `RawVec`. pub fn alloc_mut(&mut self) -> &mut A { &mut self.a } @@ -247,7 +247,7 @@ impl<T, A: Alloc> RawVec<T, A> { /// /// # Panics /// - /// * Panics if T is zero-sized on the assumption that you managed to exhaust + /// * Panics if `T` is zero-sized on the assumption that you managed to exhaust /// all `usize::MAX` slots in your imaginary buffer. /// * Panics on 32-bit platforms if the requested capacity exceeds /// `isize::MAX` bytes. @@ -290,20 +290,20 @@ impl<T, A: Alloc> RawVec<T, A> { unsafe { let elem_size = mem::size_of::<T>(); - // since we set the capacity to usize::MAX when elem_size is - // 0, getting to here necessarily means the RawVec is overfull. + // Since we set the capacity to `usize::MAX` when `elem_size` is + // 0, getting to here necessarily means the `RawVec` is overfull. assert!(elem_size != 0, "capacity overflow"); let (new_cap, uniq) = match self.current_layout() { Some(cur) => { // Since we guarantee that we never allocate more than - // isize::MAX bytes, `elem_size * self.cap <= isize::MAX` as + // `isize::MAX` bytes, `elem_size * self.cap <= isize::MAX` as // a precondition, so this can't overflow. Additionally the // alignment will never be too large as to "not be // satisfiable", so `Layout::from_size_align` will always // return `Some`. // - // tl;dr; we bypass runtime checks due to dynamic assertions + // TL;DR, we bypass runtime checks due to dynamic assertions // in this module, allowing us to use // `from_size_align_unchecked`. let new_cap = 2 * self.cap; @@ -320,8 +320,8 @@ impl<T, A: Alloc> RawVec<T, A> { } } None => { - // skip to 4 because tiny Vec's are dumb; but not if that - // would cause overflow + // Skip to 4 because tiny `Vec`'s are dumb; but not if that + // would cause overflow. let new_cap = if elem_size > (!0) / 8 { 1 } else { 4 }; match self.a.alloc_array::<T>(new_cap) { Ok(ptr) => (new_cap, ptr.into()), @@ -342,7 +342,7 @@ impl<T, A: Alloc> RawVec<T, A> { /// /// # Panics /// - /// * Panics if T is zero-sized on the assumption that you managed to exhaust + /// * Panics if `T` is zero-sized on the assumption that you managed to exhaust /// all `usize::MAX` slots in your imaginary buffer. /// * Panics on 32-bit platforms if the requested capacity exceeds /// `isize::MAX` bytes. @@ -356,15 +356,15 @@ impl<T, A: Alloc> RawVec<T, A> { None => return false, // nothing to double }; - // since we set the capacity to usize::MAX when elem_size is - // 0, getting to here necessarily means the RawVec is overfull. + // Since we set the capacity to `usize::MAX` when `elem_size` is + // 0, getting to here necessarily means the `RawVec` is overfull. assert!(elem_size != 0, "capacity overflow"); - // Since we guarantee that we never allocate more than isize::MAX + // Since we guarantee that we never allocate more than `isize::MAX` // bytes, `elem_size * self.cap <= isize::MAX` as a precondition, so // this can't overflow. // - // Similarly like with `double` above we can go straight to + // Similarly to with `double` above, we can go straight to // `Layout::from_size_align_unchecked` as we know this won't // overflow and the alignment is sufficiently small. let new_cap = 2 * self.cap; @@ -409,7 +409,7 @@ impl<T, A: Alloc> RawVec<T, A> { /// /// # Aborts /// - /// Aborts on OOM + /// Aborts on OOM. pub fn reserve_exact(&mut self, used_capacity: usize, needed_extra_capacity: usize) { match self.reserve_internal(used_capacity, needed_extra_capacity, Infallible, Exact) { Err(CapacityOverflow) => capacity_overflow(), @@ -424,7 +424,7 @@ impl<T, A: Alloc> RawVec<T, A> { fn amortized_new_size(&self, used_capacity: usize, needed_extra_capacity: usize) -> Result<usize, TryReserveError> { - // Nothing we can really do about these checks :( + // Nothing we can really do about these checks, sadly. let required_cap = used_capacity.checked_add(needed_extra_capacity) .ok_or(CapacityOverflow)?; // Cannot overflow, because `cap <= isize::MAX`, and type of `cap` is `usize`. @@ -459,7 +459,7 @@ impl<T, A: Alloc> RawVec<T, A> { /// /// # Aborts /// - /// Aborts on OOM + /// Aborts on OOM. /// /// # Examples /// @@ -538,7 +538,7 @@ impl<T, A: Alloc> RawVec<T, A> { // Here, `cap < used_capacity + needed_extra_capacity <= new_cap` // (regardless of whether `self.cap - used_capacity` wrapped). - // Therefore we can safely call grow_in_place. + // Therefore, we can safely call `grow_in_place`. let new_layout = Layout::new::<T>().repeat(new_cap).unwrap().0; // FIXME: may crash and burn on over-reserve @@ -576,14 +576,14 @@ impl<T, A: Alloc> RawVec<T, A> { return; } - // This check is my waterloo; it's the only thing Vec wouldn't have to do. + // This check is my waterloo; it's the only thing `Vec` wouldn't have to do. assert!(self.cap >= amount, "Tried to shrink to a larger capacity"); if amount == 0 { // We want to create a new zero-length vector within the - // same allocator. We use ptr::write to avoid an + // same allocator. We use `ptr::write` to avoid an // erroneous attempt to drop the contents, and we use - // ptr::read to sidestep condition against destructuring + // `ptr::read` to sidestep condition against destructuring // types that implement Drop. unsafe { @@ -600,7 +600,7 @@ impl<T, A: Alloc> RawVec<T, A> { // // We also know that `self.cap` is greater than `amount`, and // consequently we don't need runtime checks for creating either - // layout + // layout. let old_size = elem_size * self.cap; let new_size = elem_size * amount; let align = mem::align_of::<T>(); @@ -653,7 +653,7 @@ impl<T, A: Alloc> RawVec<T, A> { return Ok(()); } - // Nothing we can really do about these checks :( + // Nothing we can really do about these checks, sadly. let new_cap = match strategy { Exact => used_capacity.checked_add(needed_extra_capacity).ok_or(CapacityOverflow)?, Amortized => self.amortized_new_size(used_capacity, needed_extra_capacity)?, @@ -692,7 +692,7 @@ impl<T> RawVec<T, Global> { /// Converts the entire buffer into `Box<[T]>`. /// /// Note that this will correctly reconstitute any `cap` changes - /// that may have been performed. (see description of type for details) + /// that may have been performed. (See description of type for details.) /// /// # Undefined Behavior /// @@ -700,7 +700,7 @@ impl<T> RawVec<T, Global> { /// the rules around uninitialized boxed values are not finalized yet, /// but until they are, it is advisable to avoid them. pub unsafe fn into_box(self) -> Box<[T]> { - // NOTE: not calling `capacity()` here, actually using the real `cap` field! + // NOTE: not calling `capacity()` here; actually using the real `cap` field! let slice = slice::from_raw_parts_mut(self.ptr(), self.cap); let output: Box<[T]> = Box::from_raw(slice); mem::forget(self); @@ -709,7 +709,7 @@ impl<T> RawVec<T, Global> { } impl<T, A: Alloc> RawVec<T, A> { - /// Frees the memory owned by the RawVec *without* trying to Drop its contents. + /// Frees the memory owned by the `RawVec` *without* trying to drop its contents. pub unsafe fn dealloc_buffer(&mut self) { let elem_size = mem::size_of::<T>(); if elem_size != 0 { @@ -721,22 +721,20 @@ impl<T, A: Alloc> RawVec<T, A> { } unsafe impl<#[may_dangle] T, A: Alloc> Drop for RawVec<T, A> { - /// Frees the memory owned by the RawVec *without* trying to Drop its contents. + /// Frees the memory owned by the `RawVec` *without* trying to drop its contents. fn drop(&mut self) { unsafe { self.dealloc_buffer(); } } } - - // We need to guarantee the following: -// * We don't ever allocate `> isize::MAX` byte-size objects -// * We don't overflow `usize::MAX` and actually allocate too little +// * We don't ever allocate `> isize::MAX` byte-size objects. +// * We don't overflow `usize::MAX` and actually allocate too little. // // On 64-bit we just need to check for overflow since trying to allocate // `> isize::MAX` bytes will surely fail. On 32-bit and 16-bit we need to add // an extra guard for this in case we're running on a platform which can use -// all 4GB in user-space. e.g., PAE or x32 +// all 4GB in user-space, e.g., PAE or x32. #[inline] fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> { @@ -751,5 +749,5 @@ fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> { // ensure that the code generation related to these panics is minimal as there's // only one location which panics rather than a bunch throughout the module. fn capacity_overflow() -> ! { - panic!("capacity overflow") + panic!("capacity overflow"); } |
