Add opt-for-size core lib feature flag
Adds a feature flag to the core library that enables the possibility to have smaller implementations for certain algorithms.
So far, the core lib has traded performance for binary size. This is likely what most people want since they have big simd-capable machines. However, people on small machines, like embedded devices, don't enjoy the potential speedup of the bigger algorithms, but do have to pay for them. These microcontrollers often only have 16-1024kB of flash memory.
This PR is the result of some talks with project members like `@Amanieu` at RustNL.
There are some open questions of how this is eventually stabilized, but it's a similar question as with the existing `panic_immediate_abort` feature.
Speaking as someone from the embedded side, we'd rather have this unstable for a while as opposed to not having it at all. In the meantime we can try to use it and also add additional PRs to the core lib that uses the feature flag in areas where we find benefit.
Open questions from my side:
- Is this a good feature name?
- `panic_immediate_abort` is fairly verbose, so I went with something equally verbose
- It's easy to refactor later
- I've added the feature to `std` and `alloc` as well as they might benefit too. Do we agree?
- I expect these to get less usage out of the flag since most size-constraint projects don't use these libraries often.
Add `fn into_raw_with_allocator` to Rc/Arc/Weak.
Split out from #119761
Add `fn into_raw_with_allocator` for `Rc`/`rc::Weak`[^1]/`Arc`/`sync::Weak`.
* Pairs with `from_raw_in` (which already exists on all 4 types).
* Name matches `Box::into_raw_with_allocator`.
* Associated fns on `Rc`/`Arc`, methods on `Weak`s.
<details> <summary>Future PR/ACP</summary>
As a follow-on to this PR, I plan to make a PR/ACP later to move `into_raw(_parts)` from `Container<_, A: Allocator>` to only `Container<_, Global>` (where `Container` = `Vec`/`Box`/`Rc`/`rc::Weak`/`Arc`/`sync::Weak`) so that users of non-`Global` allocators have to explicitly handle the allocator when using `into_raw`-like APIs.
The current behaviors of stdlib containers are inconsistent with respect to what happens to the allocator when `into_raw` is called (which does not return the allocator)
| Type | `into_raw` currently callable with | behavior of `into_raw`|
| --- | --- | --- |
| `Box` | any allocator | allocator is [dropped](https://doc.rust-lang.org/nightly/src/alloc/boxed.rs.html#1060) |
| `Vec` | any allocator | allocator is [forgotten](https://doc.rust-lang.org/nightly/src/alloc/vec/mod.rs.html#884) |
| `Arc`/`Rc`/`Weak` | any allocator | allocator is [forgotten](https://doc.rust-lang.org/src/alloc/sync.rs.html#1487)(Arc) [(sync::Weak)](https://doc.rust-lang.org/src/alloc/sync.rs.html#2726) [(Rc)](https://doc.rust-lang.org/src/alloc/rc.rs.html#1352) [(rc::Weak)](https://doc.rust-lang.org/src/alloc/rc.rs.html#2993) |
In my opinion, neither implicitly dropping nor implicitly forgetting the allocator is ideal; dropping it could immediately invalidate the returned pointer, and forgetting it could unintentionally leak memory. My (to-be) proposed solution is to just forbid calling `into_raw(_parts)` on containers with non-`Global` allocators, and require calling `into_raw_with_allocator`(/`Vec::into_raw_parts_with_alloc`)
</details>
[^1]: Technically, `rc::Weak::into_raw_with_allocator` is not newly added, as it was modified and renamed from `rc::Weak::into_raw_and_alloc`.
Fix#124275: Implemented Default for `Arc<str>`
With added implementations.
```
GOOD Arc<CStr>
BROKEN Arc<OsStr> // removed
GOOD Rc<str>
GOOD Rc<CStr>
BROKEN Rc<OsStr> // removed
GOOD Rc<[T]>
GOOD Arc<[T]>
```
For discussion of https://github.com/rust-lang/rust/pull/124367#issuecomment-2091940137.
Key pain points currently:
> I've had a guess at the best locations/feature attrs for them but they might not be correct.
> However I'm unclear how to get the OsStr impl to compile, which file should they go in to avoid the error below? Is it possible, perhaps with some special std rust lib magic?
alloc: implement FromIterator for Box<str>
`Box<[T]>` implements `FromIterator<T>` using `Vec<T>` + `into_boxed_slice()`.
Add analogous `FromIterator` implementations for `Box<str>`
matching the current implementations for `String`.
Remove the `Global` allocator requirement for `FromIterator<Box<str>>` too.
ACP: https://github.com/rust-lang/libs-team/issues/196
LLVM currently adds a redundant check for the returned option, in addition
to the `self.ptr != self.end` check when using the default
`Iterator::fold` method that calls `vec::IntoIter::next` in a loop.
Relax allocator requirements on some Rc/Arc APIs.
Split out from #119761
* Remove `A: Clone` bound from `Rc::assume_init`(s), `Rc::downcast`, and `Rc::downcast_unchecked` (`Arc` methods were already relaxed by #120445)
* Make `From<Rc<[T; N]>> for Rc<[T]>` allocator-aware (`Arc`'s already is).
* Remove `A: Clone` from `Rc/Arc::unwrap_or_clone`
Internal changes:
* Made `Arc::internal_into_inner_with_allocator` method into `Arc::into_inner_with_allocator` associated fn.
* Add private `Rc::into_inner_with_allocator` (to match Arc), so other fns don't have to juggle `ManuallyDrop`.
* Remove A: Clone bound from Rc::assume_init, Rc::downcast, and Rc::downcast_unchecked.
* Make From<Rc<[T; N]>> for Rc<[T]> allocator-aware.
Internal changes:
* Made Arc::internal_into_inner_with_allocator method into Arc::into_inner_with_allocator associated fn.
* Add private Rc::into_inner_with_allocator (to match Arc), so other fns don't have to juggle ManuallyDrop.
Documentation of these properties previously existed in a lone paragraph
in the `fmt` module's documentation:
<https://doc.rust-lang.org/1.78.0/std/fmt/index.html#formatting-traits>
However, users looking to implement a formatting trait won't necessarily
look there. Therefore, let's add the critical information (that
formatting per se is infallible) to all the involved items.
Box<[T]> implements FromIterator<T> using Vec<T> + into_boxed_slice().
Add analogous FromIterator implementations for Box<str>
matching the current implementations for String.
Remove the Global allocator requirement for FromIterator<Box<str>> too.
Describe and use CStr literals in CStr and CString docs
Mention CStr literals in the description of both types, and use them in some of the code samples for CStr. This is intended to make C string literals more discoverable.
Additionally, I don't think the orange "This example is not tested" warnings are very encouraging, so I have made the examples on `CStr` build.
String.truncate comment microfix (greater or equal)
String.truncate calls Vec.truncate, in turn, and that states "is greater or equal to". Beside common sense.
deref patterns: impl `DerefPure` for more std types
Context: [deref patterns](https://github.com/rust-lang/rust/issues/87121). The requirements of `DerefPure` aren't precise yet, but these types unambiguously satisfy them.
Interestingly, a hypothetical `impl DerefMut for Cow` that does a `Clone` would *not* be eligible for `DerefPure` if we allow mixing deref patterns with normal patterns. If the following is exhaustive then the `DerefMut` would cause UB:
```rust
match &mut Cow::Borrowed(&()) {
Cow::Owned(_) => ..., // Doesn't match
deref!(_x) if false => ..., // Causes the variant to switch to `Owned`
Cow::Borrowed(_) => ..., // Doesn't match
// We reach unreachable
}
```