summary refs log tree commit diff
path: root/library/alloc/tests
AgeCommit message (Collapse)AuthorLines
2022-06-19Fix documentation for with_capacity and reserve families of methodsjmaargh-0/+9
Documentation for the following methods with_capacity with_capacity_in with_capacity_and_hasher reserve reserve_exact try_reserve try_reserve_exact was inconsistent and often not entirely correct where they existed on the following types Vec VecDeque String OsString PathBuf BinaryHeap HashSet HashMap BufWriter LineWriter since the allocator is allowed to allocate more than the requested capacity in all such cases, and will frequently "allocate" much more in the case of zero-sized types (I also checked BufReader, but there the docs appear to be accurate as it appears to actually allocate the exact capacity). Some effort was made to make the documentation more consistent between types as well. Fix with_capacity* methods for Vec Fix *reserve* methods for Vec Fix docs for *reserve* methods of VecDeque Fix docs for String::with_capacity Fix docs for *reserve* methods of String Fix docs for OsString::with_capacity Fix docs for *reserve* methods on OsString Fix docs for with_capacity* methods on HashSet Fix docs for *reserve methods of HashSet Fix docs for with_capacity* methods of HashMap Fix docs for *reserve methods on HashMap Fix expect messages about OOM in doctests Fix docs for BinaryHeap::with_capacity Fix docs for *reserve* methods of BinaryHeap Fix typos Fix docs for with_capacity on BufWriter and LineWriter Fix consistent use of `hasher` between `HashMap` and `HashSet` Fix warning in doc test Add test for capacity of vec with ZST Fix doc test error
2022-06-08Stabilize `const_intrinsic_copy`Yuki Okushi-1/+0
2022-06-04Rollup merge of #96642 - thomcc:thinbox-zst-ugh, r=yaahcDylan DPC-0/+232
Avoid zero-sized allocs in ThinBox if T and H are both ZSTs. This was surprisingly tricky, and took longer to get right than expected. `ThinBox` is a surprisingly subtle piece of code. That said, in the end, a lot of this was due to overthinking[^overthink] -- ultimately the fix ended up fairly clean and simple. [^overthink]: Honestly, for a while I was convinced this couldn't be done without allocations or runtime branches in these cases, but that's obviously untrue. Anyway, as a result of spending all that time debugging, I've extended the tests quite a bit, and also added more debug assertions. Many of these helped for subtle bugs I made in the middle (for example, the alloc/drop tracking is because I ended up double-dropping the value in the case where both were ZSTs), they're arguably a bit of overkill at this point, although I imagine they could help in the future too. Anyway, these tests cover a wide range of size/align cases, nd fully pass under miri[^1]. They also do some smoke-check asserting that the value has the correct alignment, although in practice it's totally within the compiler's rights to delete these assertions since we'd have already done UB if they get hit. They have more boilerplate than they really need, but it's not *too* bad on a per-test basis. A notable absence from testing is atypical header types, but at the moment it's impossible to manually implement `Pointee`. It would be really nice to have testing here, since it's not 100% obvious to me that the aligned read/write we use for `H` are correct in the face of arbitrary combinations of `size_of::<H>()`, `align_of::<H>()`, and `align_of::<T>()`. (That said, I spent a while thinking through it and am *pretty* sure it's fine -- I'd just feel... better if we could test some cases for non-ZST headers which have unequal and align). [^1]: Or at least, they pass under miri if I copy the code and tests into a new crate and run miri on it (after making it less stdlibified). Fixes #96485. I'd request review ``@yaahc,`` but I believe you're taking some time away from reviews, so I'll request from the previous PR's reviewer (I think that the context helps, even if the actual change didn't end up being bad here). r? ``@joshtriplett``
2022-05-29Use Box::new() instead of box syntax in alloc testsest31-12/+12
2022-05-27Avoid zero-sized allocs in ThinBox if T and H are both ZSTs.Thom Chiovoloni-0/+232
2022-05-26improve case conversion happy pathConrad Ludgate-0/+14
2022-05-02Rollup merge of #94126 - ssomers:alloc_prep_1, r=Mark-SimulacrumYuki Okushi-1173/+0
Classify BinaryHeap & LinkedList unit tests as such All but one of these so-called integration test case are unit tests, just like btree's were (#75531). In addition, reunite the unit tests of linked_list that were split off during #23104 because they needed to remain unit tests (they were later moved to the separate file they are in during #63207). The two sets could remain separate files, but I opted to merge them back together, more or less in the order they used to be, apart from one duplicate name `test_split_off` and one duplicate tiny function `list_from`.
2022-04-27Remove use of reverted std::ffi::c_charJosh Triplett-1/+2
2022-04-14library: Use type aliases to make `CStr(ing)` in libcore/liballoc unstableVadim Petrochenkov-0/+1
2022-04-14library: Move `CStr` to libcore, and `CString` to liballocVadim Petrochenkov-0/+20
2022-04-11impl const Default for Box<[T]> and Box<str>Josh Stone-0/+6
2022-04-10thin_box test: import from std, not allocRalf Jung-1/+1
2022-04-08Add ThinBox type for 1 stack pointer sized heap allocated trait objectsJane Lusby-0/+28
Relevant commit messages from squashed history in order: Add initial version of ThinBox update test to actually capture failure swap to middle ptr impl based on matthieu-m's design Fix stack overflow in debug impl The previous version would take a `&ThinBox<T>` and deref it once, which resulted in a no-op and the same type, which it would then print causing an endless recursion. I've switched to calling `deref` by name to let method resolution handle deref the correct number of times. I've also updated the Drop impl for good measure since it seemed like it could be falling prey to the same bug, and I'll be adding some tests to verify that the drop is happening correctly. add test to verify drop is behaving add doc examples and remove unnecessary Pointee bounds ThinBox: use NonNull ThinBox: tests for size Apply suggestions from code review Co-authored-by: Alphyr <47725341+a1phyr@users.noreply.github.com> use handle_alloc_error and fix drop signature update niche and size tests add cfg for allocating APIs check null before calculating offset add test for zst and trial usage prevent optimizer induced ub in drop and cleanup metadata gathering account for arbitrary size and alignment metadata Thank you nika and thomcc! Update library/alloc/src/boxed/thin.rs Co-authored-by: Josh Triplett <josh@joshtriplett.org> Update library/alloc/src/boxed/thin.rs Co-authored-by: Josh Triplett <josh@joshtriplett.org>
2022-04-08add `<[[T; N]]>::flatten`, `<[[T; N]]>::flatten_mut`, and `Vec::<[T; ↵Cyborus04-0/+8
N]>::into_flattened`
2022-03-31make utf8_char_counts test faster in MiriRalf Jung-4/+7
2022-03-31Rollup merge of #95298 - ↵Dylan DPC-0/+28
jhorstmann:fix-double-drop-of-allocator-in-vec-into-iter, r=oli-obk Fix double drop of allocator in IntoIter impl of Vec Fixes #95269 The `drop` impl of `IntoIter` reconstructs a `RawVec` from `buf`, `cap` and `alloc`, when that `RawVec` is dropped it also drops the allocator. To avoid dropping the allocator twice we wrap it in `ManuallyDrop` in the `InttoIter` struct. Note this is my first contribution to the standard library, so I might be missing some details or a better way to solve this.
2022-03-27Debug print char 0 as '\0' rather than '\u{0}'David Tolnay-2/+2
2022-03-25Add another assertion without into_iterJörn Horstmann-2/+6
2022-03-25Add a test verifying the number of drop callsJörn Horstmann-0/+24
2022-03-11Classify BinaryHeap & LinkedList unit tests as suchStein Somers-1173/+0
2022-03-10Rollup merge of #93950 - T-O-R-U-S:use-modern-formatting-for-format!-macros, ↵Dylan DPC-32/+32
r=Mark-Simulacrum Use modern formatting for format! macros This updates the standard library's documentation to use the new format_args syntax. The documentation is worthwhile to update as it should be more idiomatic (particularly for features like this, which are nice for users to get acquainted with). The general codebase is likely more hassle than benefit to update: it'll hurt git blame, and generally updates can be done by folks updating the code if (and when) that makes things more readable with the new format. A few places in the compiler and library code are updated (mostly just due to already having been done when this commit was first authored). `eprintln!("{}", e)` becomes `eprintln!("{e}")`, but `eprintln!("{}", e.kind())` remains untouched.
2022-03-10Use implicit capture syntax in format_argsT-O-R-U-S-32/+32
This updates the standard library's documentation to use the new syntax. The documentation is worthwhile to update as it should be more idiomatic (particularly for features like this, which are nice for users to get acquainted with). The general codebase is likely more hassle than benefit to update: it'll hurt git blame, and generally updates can be done by folks updating the code if (and when) that makes things more readable with the new format. A few places in the compiler and library code are updated (mostly just due to already having been done when this commit was first authored).
2022-03-10Revert accidental stabilizationOli Scherer-1/+1
2022-02-13stabilize const_ptr_offsetSaltyKitkat-1/+0
2022-02-07Add {floor,ceil}_char_boundary methods to strltdk-0/+93
2022-02-05Ensure non-power-of-two sizes are tested in the Chars::count testThom Chiovoloni-2/+4
2022-02-05Optimize `core::str::Chars::count`Thom Chiovoloni-0/+40
2022-01-17Stabilize vec_spare_capacityAmanieu d'Antras-1/+0
Closes #75017
2022-01-16Auto merge of #92598 - Badel2:panic-update-hook, r=yaahcbors-3/+3
Implement `panic::update_hook` Add a new function `panic::update_hook` to allow creating panic hooks that forward the call to the previously set panic hook, without race conditions. It works by taking a closure that transforms the old panic hook into a new one, while ensuring that during the execution of the closure no other thread can modify the panic hook. This is a small function so I hope it can be discussed here without a formal RFC, however if you prefer I can write one. Consider the following example: ```rust let prev = panic::take_hook(); panic::set_hook(Box::new(move |info| { println!("panic handler A"); prev(info); })); ``` This is a common pattern in libraries that need to do something in case of panic: log panic to a file, record code coverage, send panic message to a monitoring service, print custom message with link to github to open a new issue, etc. However it is impossible to avoid race conditions with the current API, because two threads can execute in this order: * Thread A calls `panic::take_hook()` * Thread B calls `panic::take_hook()` * Thread A calls `panic::set_hook()` * Thread B calls `panic::set_hook()` And the result is that the original panic hook has been lost, as well as the panic hook set by thread A. The resulting panic hook will be the one set by thread B, which forwards to the default panic hook. This is not considered a big issue because the panic handler setup is usually run during initialization code, probably before spawning any other threads. Using the new `panic::update_hook` function, this race condition is impossible, and the result will be either `A, B, original` or `B, A, original`. ```rust panic::update_hook(|prev| { Box::new(move |info| { println!("panic handler A"); prev(info); }) }); ``` I found one real world use case here: https://github.com/dtolnay/proc-macro2/blob/988cf403e741aadfd5340bbf67e35e1062a526aa/src/detection.rs#L32 the workaround is to detect the race condition and panic in that case. The pattern of `take_hook` + `set_hook` is very common, you can see some examples in this pull request, so I think it's natural to have a function that combines them both. Also using `update_hook` instead of `take_hook` + `set_hook` reduces the number of calls to `HOOK_LOCK.write()` from 2 to 1, but I don't expect this to make any difference in performance. ### Unresolved questions: * `panic::update_hook` takes a closure, if that closure panics the error message is "panicked while processing panic" which is not nice. This is a consequence of holding the `HOOK_LOCK` while executing the closure. Could be avoided using `catch_unwind`? * Reimplement `panic::set_hook` as `panic::update_hook(|_prev| hook)`?
2022-01-09eplace usages of vec![].into_iter with [].into_iterLucas Kent-29/+28
2022-01-08Change panic::update_hook to simplify usageBadel2-6/+4
And to remove possibility of panics while changing the panic handler, because that resulted in a double panic.
2022-01-07Implement panic::update_hookBadel2-6/+8
2022-01-04Rollup merge of #91884 - woppopo:const_box, r=oli-obkMatthias Krüger-3/+123
Constify `Box<T, A>` methods Tracking issue: none yet Most of the methods bounded on `~const`. `intrinsics::const_eval_select` is used for handling an allocation error. <details><summary>Constified API</summary> ```rust impl<T, A: Allocator> Box<T, A> { pub const fn new_in(x: T, alloc: A) -> Self where A: ~const Allocator + ~const Drop; pub const fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError> where T: ~const Drop, A: ~const Allocator + ~const Drop; pub const fn new_uninit_in(alloc: A) -> Box<mem::MaybeUninit<T>, A> where A: ~const Allocator + ~const Drop; pub const fn try_new_uninit_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError> where A: ~const Allocator + ~const Drop; pub const fn new_zeroed_in(alloc: A) -> Box<mem::MaybeUninit<T>, A> where A: ~const Allocator + ~const Drop; pub const fn try_new_zeroed_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError> where A: ~const Allocator + ~const Drop; pub const fn pin_in(x: T, alloc: A) -> Pin<Self> where A: 'static, A: 'static + ~const Allocator + ~const Drop, pub const fn into_boxed_slice(boxed: Self) -> Box<[T], A>; pub const fn into_inner(boxed: Self) -> T where Self: ~const Drop, } impl<T, A: Allocator> Box<MaybeUninit<T>, A> { pub const unsafe fn assume_init(self) -> Box<T, A>; pub const fn write(mut boxed: Self, value: T) -> Box<T, A>; pub const unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self; pub const fn into_raw_with_allocator(b: Self) -> (*mut T, A); pub const fn into_unique(b: Self) -> (Unique<T>, A); pub const fn allocator(b: &Self) -> &A; pub const fn leak<'a>(b: Self) -> &'a mut T where A: 'a; pub const fn into_pin(boxed: Self) -> Pin<Self> where A: 'static; } unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> const Drop for Box<T, A>; impl<T: ?Sized, A: Allocator> const From<Box<T, A>> for Pin<Box<T, A>> where A: 'static; impl<T: ?Sized, A: Allocator> const Deref for Box<T, A>; impl<T: ?Sized, A: Allocator> const DerefMut for Box<T, A>; impl<T: ?Sized, A: Allocator> const Unpin for Box<T, A> where A: 'static; ``` </details> <details><summary>Example</summary> ```rust pub struct ConstAllocator; unsafe impl const Allocator for ConstAllocator { fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> { unsafe { let ptr = core::intrinsics::const_allocate(layout.size(), layout.align()); Ok(NonNull::new_unchecked(ptr as *mut [u8; 0] as *mut [u8])) } } unsafe fn deallocate(&self, _ptr: NonNull<u8>, _layout: Layout) { /* do nothing */ } fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> { self.allocate(layout) } unsafe fn grow( &self, _ptr: NonNull<u8>, _old_layout: Layout, _new_layout: Layout, ) -> Result<NonNull<[u8]>, AllocError> { unimplemented!() } unsafe fn grow_zeroed( &self, _ptr: NonNull<u8>, _old_layout: Layout, _new_layout: Layout, ) -> Result<NonNull<[u8]>, AllocError> { unimplemented!() } unsafe fn shrink( &self, _ptr: NonNull<u8>, _old_layout: Layout, _new_layout: Layout, ) -> Result<NonNull<[u8]>, AllocError> { unimplemented!() } fn by_ref(&self) -> &Self where Self: Sized, { self } } #[test] fn const_box() { const VALUE: u32 = { let mut boxed = Box::new_in(1u32, ConstAllocator); assert!(*boxed == 1); *boxed = 42; assert!(*boxed == 42); *boxed }; assert!(VALUE == 42); } ``` </details>
2021-12-23Constify `Box<T, A>` methodswoppopo-3/+123
2021-12-23Rollup merge of #88858 - spektom:to_lower_upper_rev, r=dtolnayMatthias Krüger-0/+31
Allow reverse iteration of lowercase'd/uppercase'd chars The PR implements `DoubleEndedIterator` trait for `ToLowercase` and `ToUppercase`. This enables reverse iteration of lowercase/uppercase variants of character sequences. One of use cases: determining whether a char sequence is a suffix of another one. Example: ```rust fn endswith_ignore_case(s1: &str, s2: &str) -> bool { for eob in s1 .chars() .flat_map(|c| c.to_lowercase()) .rev() .zip_longest(s2.chars().flat_map(|c| c.to_lowercase()).rev()) { match eob { EitherOrBoth::Both(c1, c2) => { if c1 != c2 { return false; } } EitherOrBoth::Left(_) => return true, EitherOrBoth::Right(_) => return false, } } true } ```
2021-12-15Rollup merge of #91916 - steffahn:fix-typos, r=dtolnayMatthias Krüger-2/+2
Fix a bunch of typos I hope that none of these files is not supposed to be modified. FYI, I opened separate PRs for typos in submodules, in the respective repositories * https://github.com/rust-lang/stdarch/pull/1267 * https://github.com/rust-lang/backtrace-rs/pull/455
2021-12-14Rollup merge of #89825 - martinvonz:split-inclusive-empty, r=m-ou-seMatthias Krüger-4/+4
Make split_inclusive() on an empty slice yield an empty output `[].split_inclusive()` currently yields a single, empty slice. That's different from `"".split_inslusive()`, which yields no output at all. I think that makes the slice version harder to use. The case where I ran into this bug was when writing code for generating a diff between two slices of bytes. I wanted to prefix removed lines with "-" and a added lines with "+". Due to `split_inclusive()`'s current behavior, that means that my code prints just a "-" or "+" for empty files. I suspect most existing callers have similar "bugs" (which would be fixed by this patch). Closes #89716.
2021-12-14Fix a bunch of typosFrank Steffahn-2/+2
2021-11-19Fix Iterator::advance_by contract inconsistencyThe8472-0/+3
The `advance_by(n)` docs state that in the error case `Err(k)` that k is always less than n. It also states that `advance_by(0)` may return `Err(0)` to indicate an exhausted iterator. These statements are inconsistent. Since only one implementation (Skip) actually made use of that I changed it to return Ok(()) in that case too. While adding some tests I also found a bug in `Take::advance_back_by`.
2021-11-18Make slice->str conversion and related functions constMaybe Waffle-3/+62
This commit makes the following functions from `core::str` `const fn`: - `from_utf8[_mut]` (`feature(const_str_from_utf8)`) - `from_utf8_unchecked_mut` (`feature(const_str_from_utf8_unchecked_mut)`) - `Utf8Error::{valid_up_to,error_len}` (`feature(const_str_from_utf8)`)
2021-10-30Add #[must_use] to remaining core functionsJohn Kugelman-1/+1
2021-10-12Make split_inclusive() on an empty slice yield an empty outputMartin von Zweigbergk-4/+4
`[].split_inclusive()` currently yields a single, empty slice. That's different from `"".split_inslusive()`, which yields no output at all. I think that makes the slice version harder to use. The case where I ran into this bug was when writing code for generating a diff between two slices of bytes. I wanted to prefix removed lines with "-" and a added lines with "+". Due to `split_inclusive()`'s current behavior, that means that my code prints just a "-" or "+" for empty files. I suspect most existing callers have similar "bugs" (which would be fixed by this patch). Closes #89716.
2021-10-04Rollup merge of #87993 - kornelski:try_reserve_stable, r=joshtriplettJubilee-1/+0
Stabilize try_reserve Stabilization PR for the [`try_reserve` feature](https://github.com/rust-lang/rust/issues/48043#issuecomment-898040475).
2021-10-04Rollup merge of #89443 - cuviper:btree-hash-len, r=dtolnayJubilee-2/+12
Include the length in BTree hashes This change makes it consistent with `Hash` for all other collections.
2021-10-04Stabilize try_reserveKornel-1/+0
2021-10-01Include the length in BTree hashesJosh Stone-2/+12
This change makes it consistent with `Hash` for all other collections.
2021-09-30implement advance_(back_)_by on more iteratorsThe8472-0/+19
2021-09-17Stabilize `Iterator::map_while`Maybe Waffle-1/+0
2021-09-11Allow reverse iteration of lowercase'd/uppercase'd charsMichael Spector-0/+31
2021-09-01Rollup merge of #88040 - nbdd0121:btreemap, r=m-ou-seMara Bos-28/+4
BTree: remove Ord bound from new `K: Ord` bound is unnecessary on `BTree{Map,Set}::new` and their `Default` impl. No elements exist so there are nothing to compare anyway, so I don't think "future proof" would be a blocker here. This is analogous to `HashMap::new` not having a `K: Eq + Hash` bound. #79245 originally does this and for some reason drops the change to `new` and `Default`. I can see why changes to other methods like `entry` or `symmetric_difference` need to be careful but I couldn't find out any reason not to do it on `new`. Removing the bound also makes the stabilisation of `const fn new` not depending on const trait bounds. cc `@steffahn` who suggests me to make this PR. r? `@dtolnay`