Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracking Issue for maybe_uninit_write_slice #79995

Open
1 of 5 tasks
beepster4096 opened this issue Dec 13, 2020 · 11 comments
Open
1 of 5 tasks

Tracking Issue for maybe_uninit_write_slice #79995

beepster4096 opened this issue Dec 13, 2020 · 11 comments
Labels
A-raw-pointers Area: raw pointers, MaybeUninit, NonNull C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC Libs-Tracked Libs issues that are tracked on the team's project board. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@beepster4096
Copy link
Contributor

beepster4096 commented Dec 13, 2020

Feature gate: #![feature(maybe_uninit_write_slice)]

This is a tracking issue for MaybeUninit::copy_from_slice and MaybeUninit::clone_from_slice.

These methods are the equivalents of [T]::copy_from_slice and [T]::clone_from_slice for uninitialized slices.

Public API

impl<T> [MaybeUninit<T>] {
    pub fn write_copy_of_slice(&mut self, src: &[T]) -> &mut [T]
    where
        T: Copy;

    pub fn write_clone_of_slice(&mut self, src: &[T]) -> &mut [T]
    where
        T: Clone;
}

Steps / History

Unresolved Questions

@beepster4096

This comment has been minimized.

@rustbot rustbot added A-raw-pointers Area: raw pointers, MaybeUninit, NonNull C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Dec 13, 2020
@KodrAus KodrAus added the Libs-Tracked Libs issues that are tracked on the team's project board. label Dec 16, 2020
@Thomasdezeeuw
Copy link
Contributor

These functions are great additions to the MaybeUninit API.

But if may open the bikeshed, should be renamed to copy_slice and clone_slice to more closely match what the functions are actually doing? The current names are a little confusing/misleading. For example let's look at a similarly named function: MaybeUninit::write, it takes ownership of the value it writes and moves the value into the MaybeUninit. However write_slice and write_slice_cloned don't do this as they copy/clone, so I think the "write" terminology can be a bit misleading.

@SimonSapin
Copy link
Contributor

These methods are the equivalents of [T]::copy_from_slice and [T]::clone_from_slice for uninitialized slices.

This seems like a great reason to name these methods MaybeUninit::copy_from_slice and MaybeUninit::clone_from_slice

@veber-alex
Copy link
Contributor

veber-alex commented Jan 28, 2022

is it possible to add this as methods on impl<T> [MaybeUninit<T>] ?

@s1ck
Copy link

s1ck commented Sep 9, 2022

@drmeepster what are the plans on getting this stabilized?

@Noah-Kennedy
Copy link

I'm pretty interested in seeing this stabilized as well.

@Kixunil
Copy link
Contributor

Kixunil commented Sep 12, 2022

I think it just needs an ACP and approval.

@SUPERCILEX
Copy link
Contributor

Regarding the naming, I also think they should be called {copy,clone}_from_slice for consistency and ease of finding. The original reasoning for their current name is to indicate that the cloned values will NOT be dropped. However, I'd argue most people don't even realize that value replacement causes the old values to be dropped (I know I didn't until I thought about it). If you think about it for a bit it's obvious, but I don't think people associate "clone_from_slice" with "old stuff dropped". Instead, I think the docs can be a bit louder about the fact that old data won't be dropped.

@bend-n
Copy link
Contributor

bend-n commented Jan 22, 2024

These methods are the equivalents of [T]::copy_from_slice and [T]::clone_from_slice for uninitialized slices.

Then why is the api so different?

bors added a commit to rust-lang-ci/rust that referenced this issue Feb 16, 2024
Rename MaybeUninit::write_slice

A step to push rust-lang#79995 forward.

rust-lang/libs-team#122 also suggested to make them inherent methods, but they can't be — they'd conflict with slice's regular methods.
@kornelski
Copy link
Contributor

kornelski commented Feb 16, 2024

It's not possible to implement these methods as inherent methods on impl<T> [MaybeUninit<T>], because such impl overlaps with impl<T> [T]. So either they have to have a different name, or they have to require a different syntax like MaybeUninit::copy_from_slice.

rust-lang/libs-team#122 suggested renaming to standard names, and there's a precedent for using "static" methods to avoid conflicts (e.g. Arc::as_ptr(&arc)), so they've now been moved to MaybeUninit::copy_from_slice/MaybeUninit::clone_from_slice.

@beepster4096 Could you update the issue description?

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jan 12, 2025
…=tgross35

Add inherent versions of MaybeUninit methods for slices

This is my attempt to un-stall rust-lang#63569 and rust-lang#79995, by creating methods that mirror the existing `MaybeUninit` API:

```rust
impl<T> MaybeUninit<T> {
    pub fn write(&mut self, value: T) -> &mut T;
    pub fn as_bytes(&self) -> &[MaybeUninit<u8>];
    pub fn as_bytes_mut(&mut self) -> &mut [MaybeUninit<u8>];
    pub unsafe fn assume_init_drop(&mut self);
    pub unsafe fn assume_init_ref(&self) -> &T;
    pub unsafe fn assume_init_mut(&mut self) -> &mut T;
}
```

Adding these APIs:

```rust
impl<T> [MaybeUninit<T>] {
    // replacing copy_from_slice; renamed to avoid conflict
    pub fn write_copy_of_slice(&mut self, value: &[T]) -> &mut [T] where T: Copy;

    // replacing clone_from_slice; renamed to avoid conflict
    pub fn write_clone_of_slice(&mut self, value: &[T]) -> &mut [T] where T: Clone;

    // identical to non-slice versions; no conflict
    pub fn as_bytes(&self) -> &[MaybeUninit<u8>];
    pub fn as_bytes_mut(&mut self) -> &mut [MaybeUninit<u8>];
    pub unsafe fn assume_init_drop(&mut self);
    pub unsafe fn assume_init_ref(&self) -> &[T];
    pub unsafe fn assume_init_mut(&mut self) -> &mut [T];
}
```

Since the `assume_init` methods are identical to those on non-slices, they feel pretty natural. The main issue with the write methods is naming, as discussed in rust-lang#79995 among other places. My rationale:

* The term "write" should be in them somewhere, to mirror the other API, and this pretty much automatically makes them not collide with any other inherent slice methods.
* I chose `write_clone_of_slice` and `write_copy_of_slice` since `clone` and `copy` are being used as objects here, whereas they're being used as actions in `clone_from_slice` and `copy_from_slice`.

The final "weird" thing I've done in this PR is remove a link to `Vec<T>` from `assume_init_drop` (both copies, since they're effectively copied docs), since there's no good way to link to `Vec` for something that can occur both on the page for `std/primitive.slice.html` and `std/vec/struct.Vec.html`, since the code here lives in libcore and can't use intra-doc-linking to mention `Vec`. (see: rust-lang#121436)

The reason why this method shows up both on `Vec<T>` and `[T]` is because the `[T]` docs are automatically inlined on `Vec<T>`'s page, since it implements `Deref`. It's unfortunate that rustdoc doesn't have a way of dealing with this at the moment, but it is what it is, and it's a reasonable compromise for now.
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Jan 12, 2025
Rollup merge of rust-lang#129259 - clarfonthey:maybe_uninit_slices, r=tgross35

Add inherent versions of MaybeUninit methods for slices

This is my attempt to un-stall rust-lang#63569 and rust-lang#79995, by creating methods that mirror the existing `MaybeUninit` API:

```rust
impl<T> MaybeUninit<T> {
    pub fn write(&mut self, value: T) -> &mut T;
    pub fn as_bytes(&self) -> &[MaybeUninit<u8>];
    pub fn as_bytes_mut(&mut self) -> &mut [MaybeUninit<u8>];
    pub unsafe fn assume_init_drop(&mut self);
    pub unsafe fn assume_init_ref(&self) -> &T;
    pub unsafe fn assume_init_mut(&mut self) -> &mut T;
}
```

Adding these APIs:

```rust
impl<T> [MaybeUninit<T>] {
    // replacing copy_from_slice; renamed to avoid conflict
    pub fn write_copy_of_slice(&mut self, value: &[T]) -> &mut [T] where T: Copy;

    // replacing clone_from_slice; renamed to avoid conflict
    pub fn write_clone_of_slice(&mut self, value: &[T]) -> &mut [T] where T: Clone;

    // identical to non-slice versions; no conflict
    pub fn as_bytes(&self) -> &[MaybeUninit<u8>];
    pub fn as_bytes_mut(&mut self) -> &mut [MaybeUninit<u8>];
    pub unsafe fn assume_init_drop(&mut self);
    pub unsafe fn assume_init_ref(&self) -> &[T];
    pub unsafe fn assume_init_mut(&mut self) -> &mut [T];
}
```

Since the `assume_init` methods are identical to those on non-slices, they feel pretty natural. The main issue with the write methods is naming, as discussed in rust-lang#79995 among other places. My rationale:

* The term "write" should be in them somewhere, to mirror the other API, and this pretty much automatically makes them not collide with any other inherent slice methods.
* I chose `write_clone_of_slice` and `write_copy_of_slice` since `clone` and `copy` are being used as objects here, whereas they're being used as actions in `clone_from_slice` and `copy_from_slice`.

The final "weird" thing I've done in this PR is remove a link to `Vec<T>` from `assume_init_drop` (both copies, since they're effectively copied docs), since there's no good way to link to `Vec` for something that can occur both on the page for `std/primitive.slice.html` and `std/vec/struct.Vec.html`, since the code here lives in libcore and can't use intra-doc-linking to mention `Vec`. (see: rust-lang#121436)

The reason why this method shows up both on `Vec<T>` and `[T]` is because the `[T]` docs are automatically inlined on `Vec<T>`'s page, since it implements `Deref`. It's unfortunate that rustdoc doesn't have a way of dealing with this at the moment, but it is what it is, and it's a reasonable compromise for now.
@clarfonthey
Copy link
Contributor

As of #129259 these are now:

impl<T> [MaybeUninit<T>] {
    pub fn write_copy_of_slice(&mut self, value: &[T]) -> &mut [T] where T: Copy;
    pub fn write_clone_of_slice(&mut self, value: &[T]) -> &mut [T] where T: Clone;
}

Worth updating the description for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-raw-pointers Area: raw pointers, MaybeUninit, NonNull C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC Libs-Tracked Libs issues that are tracked on the team's project board. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests