about summary refs log tree commit diff
path: root/library/alloc/tests
AgeCommit message (Collapse)AuthorLines
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`
2021-08-24Fix grammarest31-4/+4
2021-08-18BTree: remove Ord bound from newGary Guo-28/+4
2021-08-17Constified `Default` implementationsDeadbeef-13/+14
The libs-api team agrees to allow const_trait_impl to appear in the standard library as long as stable code cannot be broken (they are properly gated) this means if the compiler teams thinks it's okay, then it's okay. My priority on constifying would be: 1. Non-generic impls (e.g. Default) or generic impls with no bounds 2. Generic functions with bounds (that use const impls) 3. Generic impls with bounds 4. Impls for traits with associated types For people opening constification PRs: please cc me and/or oli-obk.
2021-08-16Rollup merge of #88030 - fee1-dead:fixme, r=oli-obkMara Bos-3/+1
Assign FIXMEs to me and remove obsolete ones Also fixed capitalization of documentation We also don't need to transform predicates to be non-const since we basically ignore const predicates in non-const contexts. r? `````@oli-obk`````
2021-08-15Auto merge of #87974 - steffahn:slice_split_size_hints, r=dtolnaybors-0/+61
Test and fix `size_hint` for slice’s [r]split* iterators Adds extensive test (of `size_hint`) for all the _[r]split*_ iterators. Fixes `size_hint` upper bound for _split_inclusive*_ iterators which was one higher than necessary for non-empty slices. Fixes `size_hint` lower bound for _[r]splitn*_ iterators when _n == 0_, which was one too high. **Lower bound being one too high was a logic error, violating the correctness condition of `size_hint`.** _Edit:_ I’ve opened an issue for that bug, so this PR fixes #87978
2021-08-14Assign FIXMEs to me and remove obsolete onesDeadbeef-3/+1
Also fixed capitalization of documentation
2021-08-13Improve wording, correct -> tight.Frank Steffahn-6/+6
2021-08-13Consistent use of `impl Trait` arguments in the test's helper function.Frank Steffahn-5/+1
2021-08-13allow incomplete features for nowDeadbeef-0/+2
2021-08-13Moved ui testDeadbeef-0/+56
2021-08-12Rewrite test from previous commit but without using macros.Frank Steffahn-64/+55
2021-08-12Test and fix size_hint for slice's [r]split* iteratorsFrank Steffahn-0/+74
Adds extensive test for all the [r]split* iterators. Fixes size_hint upper bound for split_inclusive* iterators which was one higher than necessary for non-empty slices. Fixes size_hint lower bound for [r]splitn* iterators when n==0, which was one too high.
2021-08-07Use assert_matches! instead of if let {} elseKornel-292/+269
2021-08-07Auto merge of #87408 - kornelski:try_reserve_error, r=yaahcbors-87/+197
Hide allocator details from TryReserveError I think there's [no need for TryReserveError to carry detailed information](https://github.com/rust-lang/rust/issues/48043#issuecomment-825139280), but I wouldn't want that issue to delay stabilization of the `try_reserve` feature. So I'm proposing to stabilize `try_reserve` with a `TryReserveError` as an opaque structure, and if needed, expose error details later. This PR moves the `enum` to an unstable inner `TryReserveErrorKind` that lives under a separate feature flag. `TryReserveErrorKind` could possibly be left as an implementation detail forever, and the `TryReserveError` get methods such as `allocation_size() -> Option<usize>` or `layout() -> Option<Layout>` instead, or the details could be dropped completely to make try-reserve errors just a unit struct, and thus smaller and cheaper.
2021-07-29Fix may not to appropriate might not or must notAli Malik-1/+1
2021-07-24Hide allocator details from TryReserveErrorKornel-87/+197
2021-07-11Add test for the fixAlexis Bourget-0/+41
2021-06-18Lint for unused borrows as part of UNUSED_MUST_USEhi-rustin-10/+10
2021-06-06Rollup merge of #85930 - mominul:array_into_iter, r=m-ou-seYuki Okushi-5/+5
Update standard library for IntoIterator implementation of arrays This PR partially resolves issue #84513 of updating the standard library part. I haven't found any remaining doctest examples which are using iterators over e.g. &i32 instead of just i32 in the standard library. Can anyone point me to them if there's remaining any? Thanks! r? ```@m-ou-se```
2021-06-02Stabilize `vecdeque_binary_search`SOFe-1/+0
2021-06-02Update expressions where we can use array's IntoIterator implementationMuhammad Mominul Huque-5/+5
2021-05-26Rollup merge of #85625 - SkiFire13:fix-85613-vec-dedup-drop-panics, r=nagisaDylan DPC-23/+25
Prevent double drop in `Vec::dedup_by` if a destructor panics Fixes #85613
2021-05-24Make Vec::dedup panicking test actually detect double panicsGiacomo Stevanato-23/+25
2021-05-20Add Weak may_dangle testsDavid Tolnay-0/+30
2021-05-19from review: more robust testthe8472-2/+2
This also checks the contents and not only the capacity in case IntoIter's clone implementation is changed to add capacity at the end. Extra capacity at the beginning would be needed to make InPlaceIterable work. Co-authored-by: Giacomo Stevanato <giaco.stevanato@gmail.com>
2021-05-19add regression testThe8472-0/+12