Update documentation for Arc::from_raw, Arc::increment_strong_count, and Arc::decrement_strong_count to clarify allocator requirement
### Related Issue:
This update addresses parts of the issue raised in [#134242](https://github.com/rust-lang/rust/issues/134242), where Arc's documentation lacks `Global Allocator` safety descriptions for three APIs. And this was confirmed by ```@workingjubilee``` :
> Wait, nevermind. I apparently forgot the `increment_strong_count` is implicitly A = Global. Ugh. Another reason these things are hard to track, unfortunately.
### PR Description
This PR updates the document for the following APIs:
- `Arc::from_raw`
- `Arc::increment_strong_count`
- `Arc::decrement_strong_count`
These APIs currently lack an important piece of documentation: **the raw pointer must point to a block of memory allocated by the global allocator**. This crucial detail is specified in the source code but is not reflected in the documentation, which could lead to confusion or incorrect usage by users.
### Problem:
The following example demonstrates the potential confusion caused by the lack of documentation:
```rust
#![feature(allocator_api)]
use std::alloc::{Allocator,AllocError, Layout};
use std::ptr::NonNull;
use std::sync::Arc;
struct LocalAllocator {
memory: NonNull<u8>,
size: usize,
}
impl LocalAllocator {
fn new(size: usize) -> Self {
Self {
memory: unsafe { NonNull::new_unchecked(&mut 0u8 as *mut u8) },
size,
}
}
}
unsafe impl Allocator for LocalAllocator {
fn allocate(&self, _layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
Ok(NonNull::slice_from_raw_parts(self.memory, self.size))
}
unsafe fn deallocate(&self, _ptr: NonNull<u8>, _layout: Layout) {
}
}
fn main() {
let allocator = LocalAllocator::new(64);
let arc = Arc::new_in(5, &allocator); // Here, allocator could be any non-global allocator
let ptr = Arc::into_raw(arc);
unsafe {
Arc::increment_strong_count(ptr);
let arc = Arc::from_raw(ptr);
assert_eq!(2, Arc::strong_count(&arc)); // Failed here!
}
}
```
Add an example for `Vec::splice` inserting elements without removing
This example clearly showcases how `splice` can be used to insert multiple elements efficiently at an index into a vector.
Fixes#135369.
The added example:
> Using `splice` to insert new items into a vector efficiently at a specific position indicated by an empty range:
> ```rust
> let mut v = vec![1, 5];
> let new = [2, 3, 4];
> v.splice(1..1, new);
> assert_eq!(v, [1, 2, 3, 4, 5]);
> ```
`@rustbot` label A-docs A-collections
Rollup of 6 pull requests
Successful merges:
- #129259 (Add inherent versions of MaybeUninit methods for slices)
- #135374 (Suggest typo fix when trait path expression is typo'ed)
- #135377 (Make MIR cleanup for functions with impossible predicates into a real MIR pass)
- #135378 (Remove a bunch of diagnostic stashing that doesn't do anything)
- #135397 (compiletest: add erroneous variant to `string_enum`s conversions error)
- #135398 (add more crash tests)
r? `@ghost`
`@rustbot` modify labels: rollup
Use `NonNull::without_provenance` within the standard library
This API removes the need for several `unsafe` blocks, and leads to clearer code. It uses feature `nonnull_provenance` (#135243).
Close#135343
Update a bunch of library types for MCP807
This greatly reduces the number of places that actually use the `rustc_layout_scalar_valid_range_*` attributes down to just 3:
```
library/core\src\ptr\non_null.rs
68:#[rustc_layout_scalar_valid_range_start(1)]
library/core\src\num\niche_types.rs
19: #[rustc_layout_scalar_valid_range_start($low)]
20: #[rustc_layout_scalar_valid_range_end($high)]
```
Everything else -- PAL Nanoseconds, alloc's `Cap`, niched FDs, etc -- all just wrap those `niche_types` types.
r? ghost
This greatly reduces the number of places that actually use the `rustc_layout_scalar_valid_range_*` attributes down to just 3:
```
library/core\src\ptr\non_null.rs
68:#[rustc_layout_scalar_valid_range_start(1)]
library/core\src\num\niche_types.rs
19: #[rustc_layout_scalar_valid_range_start($low)]
20: #[rustc_layout_scalar_valid_range_end($high)]
```
Everything else -- PAL Nanoseconds, alloc's `Cap`, niched FDs, etc -- all just wrap those `niche_types` types.
Impl String::into_chars
Tracking issue - https://github.com/rust-lang/rust/issues/133125
r? `@programmerjake` `@kennytm` `@Amanieu`
This refers to https://github.com/rust-lang/libs-team/issues/268
Before adding tests and creating a tracking issue, I'd like to reach a consensus on the implementation direction and two questions:
1. Whether we'd add a `String::into_char_indices` method also?
2. See inline comment.
do not in-place-iterate over flatmap/flatten
The implementation is unsound when a partially consumed iterator has some elements buffered in the front/back parts and cloning the Iterator removes the capacity from the backing vec::IntoIter.
This is a fix for #135103 that removes the specialization trait impls without removing some supporting parts. I've kept it small so it can be easily backported. I'll either remove the remaining parts or think of a way to recover the optimization in a separate PR.
The implementation is unsound when a partially consumed iterator has
some elements buffered in the front/back parts and cloning the Iterator
removes the capacity from the backing vec::IntoIter.
Document collection `From` and `FromIterator` impls that drop duplicate keys.
This behavior is worth documenting because there are other plausible alternatives, such as panicking when a duplicate is encountered, and it reminds the programmer to consider whether they should, for example, coalesce duplicate keys first.
Followup to #89869.
Add `into_array` conversion destructors for `Box`, `Rc`, and `Arc`.
Tracking issue: #133508
This PR adds the `into_array` destructor for `alloc::boxed::Box<[T]>`, `alloc::rc::Rc<[T]>`, and `alloc::sync::Arc<[T]>`.
Note that this PR assumes the initial proposal of these functions returning `Option`. It is still an open question whether this should instead be `Result`. We can, however, easily change this in a follow-up PR with the necessary consensus.
Asserts the maximum value that can be returned from `Vec::len`
Currently, casting `Vec<i32>` to `Vec<u32>` takes O(1) time:
```rust
// See <https://godbolt.org/z/hxq3hnYKG> for assembly output.
pub fn cast(vec: Vec<i32>) -> Vec<u32> {
vec.into_iter().map(|e| e as _).collect()
}
```
But the generated assembly is not the same as the identity function, which prevents us from casting `Vec<Vec<i32>>` to `Vec<Vec<u32>>` within O(1) time:
```rust
// See <https://godbolt.org/z/7n48bxd9f> for assembly output.
pub fn cast(vec: Vec<Vec<i32>>) -> Vec<Vec<u32>> {
vec.into_iter()
.map(|e| e.into_iter().map(|e| e as _).collect())
.collect()
}
```
This change tries to fix the problem. You can see the comparison here: <https://godbolt.org/z/jdManrKvx>.
This behavior is worth documenting because there are other plausible
alternatives, such as panicking when a duplicate is encountered, and
it reminds the programmer to consider whether they should, for example,
coalesce duplicate keys first.
docs: Mention `spare_capacity_mut()` in `Vec::set_len`
I recently went down a small rabbit hole when trying to identify safe use of `Vec::set_len`. The solution was `Vec::spare_capacity_mut`. I think the docs on `Vec::set_len` benefit from mentioning this method.
A possible counter-argument could be that the [clippy lint `uninit_vec`](https://rust-lang.github.io/rust-clippy/master/index.html#/uninit_vec) already nudges people in the right direction. However, I think a working example on `Vec::set_len` is still beneficial.
Happy to hear your thoughts on the matter. 😊
Use field init shorthand where possible
Field init shorthand allows writing initializers like `tcx: tcx` as
`tcx`. The compiler already uses it extensively. Fix the last few places
where it isn't yet used.
EDIT: this PR also updates `rustfmt.toml` to set
`use_field_init_shorthand = true`.
Field init shorthand allows writing initializers like `tcx: tcx` as
`tcx`. The compiler already uses it extensively. Fix the last few places
where it isn't yet used.
Rollup of 7 pull requests
Successful merges:
- #130361 (std::net: Solaris supports `SOCK_CLOEXEC` as well since 11.4.)
- #133406 (Add value accessor methods to `Mutex` and `RwLock`)
- #133633 (don't show the full linker args unless `--verbose` is passed)
- #134285 (Add some convenience helper methods on `hir::Safety`)
- #134310 (Add clarity to the examples of some `Vec` & `VecDeque` methods)
- #134313 (Don't make a def id for `impl_trait_in_bindings`)
- #134315 (A couple of polonius fact generation cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
Add clarity to the examples of some `Vec` & `VecDeque` methods
In some `Vec` and `VecDeque` examples where elements are `i32`, examples can seem a bit confusing at first glance if a parameter of the method is an `usize`.
In this case, I think it's better to use `char` rather than `i32`.
> [!NOTE]
> It's already done in the implementation of `VecDeque::insert`
#### Difference
- `i32`
```rs
let mut v = vec![1, 2, 3];
assert_eq!(v.remove(1), 2);
assert_eq!(v, [1, 3]);
```
- `char`
```rs
let mut v = vec!['a', 'b', 'c'];
assert_eq!(v.remove(1), 'b');
assert_eq!(v, ['a', 'c']);
```
Even tho it's pretty minor, it's a nice to have.
`UniqueRc` trait impls
UniqueRc tracking Issue: #112566
Stable traits: (i.e. impls behind only the `unique_rc_arc` feature gate)
* Support the same formatting as `Rc`:
* `fmt::Debug` and `fmt::Display` delegate to the pointee.
* `fmt::Pointer` prints the address of the pointee.
* Add explicit `!Send` and `!Sync` impls, to mirror `Rc`.
* Borrowing traits: `Borrow`, `BorrowMut`, `AsRef`, `AsMut`
* `Rc` does not implement `BorrowMut` and `AsMut`, but `UniqueRc` can.
* Unconditional `Unpin`, like other heap-allocated types.
* Comparison traits `(Partial)Ord` and `(Partial)Eq` delegate to the pointees.
* `PartialEq for UniqueRc` does not do `Rc`'s specialization shortcut for pointer equality when `T: Eq`, since by definition two `UniqueRc`s cannot share an allocation.
* `Hash` delegates to the pointee.
* `AsRawFd`, `AsFd`, `AsHandle`, `AsSocket` delegate to the pointee like `Rc`.
* Sidenote: The bounds on `T` for the existing `Pointer<T>` impls for specifically `AsRawFd` and `AsSocket` do not allow `T: ?Sized`. For the added `UniqueRc` impls I allowed `T: ?Sized` for all four traits, but I did not change the existing (stable) impls.
Unstable traits:
* `DispatchFromDyn`, allows using `UniqueRc<Self>` as a method receiver under `feature(arbitrary_self_types)`.
* Existing `PinCoerceUnsized for UniqueRc` is generalized to allow non-`Global` allocators, like `Rc`.
* `DerefPure`, allows using `UniqueRc` in deref-patterns under `feature(deref_patterns)`, like `Rc`.
For documentation, `Rc` only has documentation on the comparison traits' methods, so I copied/adapted the documentation for those, and left the rest without impl-specific docs.
~~Edit: Marked as draft while I figure out `UnwindSafe`.~~
Edit: Ignoring `UnwindSafe` for this PR