Skip to content

Commit 9e18364

Browse files
committed
Apply doc fixes as requested
1 parent 1116df1 commit 9e18364

File tree

1 file changed

+40
-25
lines changed

1 file changed

+40
-25
lines changed

src/lib.rs

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
11
#![deny(missing_docs)]
22

3-
//! ThinVec is exactly the same as Vec, except that it stores its `len` and `capacity` in the buffer
3+
//! `ThinVec` is exactly the same as `Vec`, except that it stores its `len` and `capacity` in the buffer
44
//! it allocates.
55
//!
66
//! This makes the memory footprint of ThinVecs lower; notably in cases where space is reserved for
77
//! a non-existence `ThinVec<T>`. So `Vec<ThinVec<T>>` and `Option<ThinVec<T>>::None` will waste less
88
//! space. Being pointer-sized also means it can be passed/stored in registers.
99
//!
10-
//! Of course, any actually constructed ThinVec will theoretically have a bigger allocation, but
10+
//! Of course, any actually constructed `ThinVec` will theoretically have a bigger allocation, but
1111
//! the fuzzy nature of allocators means that might not actually be the case.
1212
//!
13-
//! Properties of Vec that are preserved:
13+
//! Properties of `Vec` that are preserved:
1414
//! * `ThinVec::new()` doesn't allocate (it points to a statically allocated singleton)
1515
//! * reallocation can be done in place
1616
//! * `size_of::<ThinVec<T>>()` == `size_of::<Option<ThinVec<T>>>()`
1717
//!
18-
//! Properties of Vec that aren't preserved:
18+
//! Properties of `Vec` that aren't preserved:
1919
//! * `ThinVec<T>` can't ever be zero-cost roundtripped to a `Box<[T]>`, `String`, or `*mut T`
2020
//! * `from_raw_parts` doesn't exist
21-
//! * ThinVec currently doesn't bother to not-allocate for Zero Sized Types (e.g. `ThinVec<()>`),
21+
//! * `ThinVec` currently doesn't bother to not-allocate for Zero Sized Types (e.g. `ThinVec<()>`),
2222
//! but it could be done if someone cared enough to implement it.
2323
//!
2424
//!
2525
//!
2626
//! # Gecko FFI
2727
//!
28-
//! If you enable the gecko-ffi feature, ThinVec will verbatim bridge with the nsTArray type in
29-
//! Gecko (Firefox). That is, ThinVec and nsTArray have identical layouts *but not ABIs*,
28+
//! If you enable the gecko-ffi feature, `ThinVec` will verbatim bridge with the nsTArray type in
29+
//! Gecko (Firefox). That is, `ThinVec` and nsTArray have identical layouts *but not ABIs*,
3030
//! so nsTArrays/ThinVecs an be natively manipulated by C++ and Rust, and ownership can be
3131
//! transferred across the FFI boundary (**IF YOU ARE CAREFUL, SEE BELOW!!**).
3232
//!
@@ -107,17 +107,17 @@
107107
//! While relocations are generally predictable if you're very careful, **you should avoid using
108108
//! types with significant locations with Rust FFI**.
109109
//!
110-
//! Specifically, ThinVec will trivially relocate its contents whenever it needs to reallocate its
110+
//! Specifically, `ThinVec` will trivially relocate its contents whenever it needs to reallocate its
111111
//! buffer to change its capacity. This is the default reallocation strategy for nsTArray, and is
112112
//! suitable for the vast majority of types. Just be aware of this limitation!
113113
//!
114114
//! ## Auto Arrays Are Dangerous
115115
//!
116-
//! ThinVec has *some* support for handling auto arrays which store their buffer on the stack,
116+
//! `ThinVec` has *some* support for handling auto arrays which store their buffer on the stack,
117117
//! but this isn't well tested.
118118
//!
119119
//! Regardless of how much support we provide, Rust won't be aware of the buffer's limited lifetime,
120-
//! so standard auto array safety caveats apply about returning/storing them! ThinVec won't ever
120+
//! so standard auto array safety caveats apply about returning/storing them! `ThinVec` won't ever
121121
//! produce an auto array on its own, so this is only an issue for transferring an nsTArray into
122122
//! Rust.
123123
//!
@@ -135,7 +135,7 @@
135135
//! defined. Specifically, we must share the symbol for nsTArray's empty singleton. You will get
136136
//! linking errors if that isn't defined.
137137
//!
138-
//! The gecko-ffi feature also limits ThinVec to the legacy behaviors of nsTArray. Most notably,
138+
//! The gecko-ffi feature also limits `ThinVec` to the legacy behaviors of nsTArray. Most notably,
139139
//! nsTArray has a maximum capacity of i32::MAX (~2.1 billion items). Probably not an issue.
140140
//! Probably.
141141
//!
@@ -175,7 +175,7 @@ mod impl_details {
175175
mod impl_details {
176176
// Support for briding a gecko nsTArray verbatim into a ThinVec.
177177
//
178-
// ThinVec can't see copy/move/delete implementations
178+
// `ThinVec` can't see copy/move/delete implementations
179179
// from C++
180180
//
181181
// The actual layout of an nsTArray is:
@@ -190,15 +190,15 @@ mod impl_details {
190190
//
191191
// Rust doesn't natively support bit-fields, so we manually mask
192192
// and shift the bit. When the "auto" bit is set, the header and buffer
193-
// are actually on the stack, meaning the ThinVec pointer-to-header
193+
// are actually on the stack, meaning the `ThinVec` pointer-to-header
194194
// is essentially an "owned borrow", and therefore dangerous to handle.
195195
// There are no safety guards for this situation.
196196
//
197197
// On little-endian platforms, the auto bit will be the high-bit of
198198
// our capacity u32. On big-endian platforms, it will be the low bit.
199199
// Hence we need some platform-specific CFGs for the necessary masking/shifting.
200200
//
201-
// ThinVec won't ever construct an auto array. They only happen when
201+
// `ThinVec` won't ever construct an auto array. They only happen when
202202
// bridging from C++. This means we don't need to ever set/preserve the bit.
203203
// We just need to be able to read and handle it if it happens to be there.
204204
//
@@ -333,6 +333,11 @@ extern "C" {
333333

334334
// Utils for computing layouts of allocations
335335

336+
/// Gets the size necessary to allocate a `ThinVec<T>` with the give capacity.
337+
///
338+
/// # Panics
339+
///
340+
/// This will panic if isize::MAX is overflowed at any point.
336341
fn alloc_size<T>(cap: usize) -> usize {
337342
// Compute "real" header size with pointer math
338343
//
@@ -353,6 +358,7 @@ fn alloc_size<T>(cap: usize) -> usize {
353358
final_size as usize
354359
}
355360

361+
/// Gets the padding necessary for the array of a `ThinVec<T>`
356362
fn padding<T>() -> usize {
357363
let alloc_align = alloc_align::<T>();
358364
let header_size = mem::size_of::<Header>();
@@ -370,14 +376,25 @@ fn padding<T>() -> usize {
370376
}
371377
}
372378

379+
/// Gets the align necessary to allocate a `ThinVec<T>`
373380
fn alloc_align<T>() -> usize {
374381
max(mem::align_of::<T>(), mem::align_of::<Header>())
375382
}
376383

384+
/// Gets the layout necessary to allocate a `ThinVec<T>`
385+
///
386+
/// # Panics
387+
///
388+
/// Panics if the required size overflows `isize::MAX`.
377389
fn layout<T>(cap: usize) -> Layout {
378390
unsafe { Layout::from_size_align_unchecked(alloc_size::<T>(cap), alloc_align::<T>()) }
379391
}
380392

393+
/// Allocates a header (and array) for a `ThinVec<T>` with the given capacity.
394+
///
395+
/// # Panics
396+
///
397+
/// Panics if the required size overflows `isize::MAX`.
381398
fn header_with_capacity<T>(cap: usize) -> NonNull<Header> {
382399
debug_assert!(cap > 0);
383400
unsafe {
@@ -467,7 +484,7 @@ impl<T> ThinVec<T> {
467484
/// If it is important to know the exact allocated capacity of a `ThinVec`,
468485
/// always use the [`capacity`] method after construction.
469486
///
470-
/// **NOTE**: unlike Vec, ThinVec **MUST** allocate to keep track of non-zero
487+
/// **NOTE**: unlike `Vec`, `ThinVec` **MUST** allocate once to keep track of non-zero
471488
/// lengths. As such, we cannot provide the same guarantees about ThinVecs
472489
/// of ZSTs not allocating. However the allocation never needs to be resized
473490
/// to add more ZSTs, since the underlying array is still length 0.
@@ -1936,7 +1953,7 @@ impl<T> From<Box<[T]>> for ThinVec<T> {
19361953
/// Convert a boxed slice into a vector by transferring ownership of
19371954
/// the existing heap allocation.
19381955
///
1939-
/// **NOTE:** unlike std, this must reallocate to change the layout!
1956+
/// **NOTE:** unlike `std`, this must reallocate to change the layout!
19401957
///
19411958
/// # Examples
19421959
///
@@ -1953,7 +1970,7 @@ impl<T> From<Box<[T]>> for ThinVec<T> {
19531970
}
19541971

19551972
impl<T> From<Vec<T>> for ThinVec<T> {
1956-
/// Convert a std::Vec into a ThinVec.
1973+
/// Convert a `std::Vec` into a `ThinVec`.
19571974
///
19581975
/// **NOTE:** this must reallocate to change the layout!
19591976
///
@@ -1966,13 +1983,12 @@ impl<T> From<Vec<T>> for ThinVec<T> {
19661983
/// assert_eq!(ThinVec::from(b), thin_vec![1, 2, 3]);
19671984
/// ```
19681985
fn from(s: Vec<T>) -> Self {
1969-
// Can just lean on the fact that `Box<[T]>` -> `Vec<T>` is Free.
19701986
s.into_iter().collect()
19711987
}
19721988
}
19731989

19741990
impl<T> From<ThinVec<T>> for Vec<T> {
1975-
/// Convert a ThinVec into a std::Vec.
1991+
/// Convert a `ThinVec` into a `std::Vec`.
19761992
///
19771993
/// **NOTE:** this must reallocate to change the layout!
19781994
///
@@ -1985,7 +2001,6 @@ impl<T> From<ThinVec<T>> for Vec<T> {
19852001
/// assert_eq!(Vec::from(b), vec![1, 2, 3]);
19862002
/// ```
19872003
fn from(s: ThinVec<T>) -> Self {
1988-
// Can just lean on the fact that `Box<[T]>` -> `Vec<T>` is Free.
19892004
s.into_iter().collect()
19902005
}
19912006
}
@@ -1996,7 +2011,7 @@ impl<T> From<ThinVec<T>> for Box<[T]> {
19962011
/// If `v` has excess capacity, its items will be moved into a
19972012
/// newly-allocated buffer with exactly the right capacity.
19982013
///
1999-
/// **NOTE:** unlike std, this must reallocate to change the layout!
2014+
/// **NOTE:** unlike `std`, this must reallocate to change the layout!
20002015
///
20012016
/// # Examples
20022017
///
@@ -2212,7 +2227,7 @@ impl<T> AsRef<[T]> for IntoIter<T> {
22122227
impl<T: Clone> Clone for IntoIter<T> {
22132228
#[allow(clippy::into_iter_on_ref)]
22142229
fn clone(&self) -> Self {
2215-
// Just create a new ThinVec from the remaining elements and IntoIter it
2230+
// Just create a new `ThinVec` from the remaining elements and IntoIter it
22162231
self.as_slice()
22172232
.into_iter()
22182233
.cloned()
@@ -2301,8 +2316,8 @@ pub struct Drain<'a, T> {
23012316
/// It's ok to use IterMut here because it promises to only take mutable
23022317
/// refs to the parts we haven't yielded yet.
23032318
///
2304-
/// A downside of this (and the *mut below is that it makes this Invariant, when
2305-
/// technically it could be covariant?)
2319+
/// A downside of this (and the *mut below) is that it makes this type invariant, when
2320+
/// technically it could be covariant?
23062321
iter: IterMut<'a, T>,
23072322
/// The actual ThinVec, which we need to hold onto to undo the leak amplification
23082323
/// and backshift the tail into place. This should only be accessed when we're
@@ -2386,7 +2401,7 @@ impl<'a, T> Drain<'a, T> {
23862401
#[must_use]
23872402
pub fn as_slice(&self) -> &[T] {
23882403
// SAFETY: this is A-OK because the elements that the underlying
2389-
// iterator still points at are still logically initialized and continguous.
2404+
// iterator still points at are still logically initialized and contiguous.
23902405
self.iter.as_slice()
23912406
}
23922407
}

0 commit comments

Comments
 (0)