Skip to content

Conversation

kpreid
Copy link
Contributor

@kpreid kpreid commented Sep 23, 2023

  • {Rc,Arc}::make_mut() now accept any type implementing the new unstable trait core::clone::CloneToUninit.
  • CloneToUninit is implemented for T: Clone and for [T] where T: Clone.
  • CloneToUninit is a generalization of the existing internal trait alloc::alloc::WriteCloneIntoRaw.
  • New feature gate: clone_to_uninit

This allows performing make_mut() on Rc<[T]> and Arc<[T]>, which was not previously possible.


Previous PR description, now obsolete:

Add {Rc, Arc}::make_mut_slice()

These functions behave identically to make_mut(), but operate on Arc<[T]> instead of Arc<T>.

This allows performing the operation on slices, which was not previously possible because make_mut() requires T: Clone (and slices, being !Sized, do not and currently cannot implement Clone).

Feature gate: make_mut_slice

try-job: test-various

@rustbot
Copy link
Collaborator

rustbot commented Sep 23, 2023

r? @thomcc

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Sep 23, 2023
@kpreid
Copy link
Contributor Author

kpreid commented Sep 23, 2023

@rustbot label +T-libs-api

@rustbot rustbot added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Sep 23, 2023
@rust-log-analyzer

This comment has been minimized.

@thomcc
Copy link
Member

thomcc commented Sep 24, 2023

This is insta-stable, so it needs libs-api FCP.

r? @rust-lang/libs-api

@rustbot rustbot assigned BurntSushi and unassigned thomcc Sep 24, 2023
@thomcc
Copy link
Member

thomcc commented Sep 24, 2023

Rerolling because @BurntSushi doesn't do libs reviews.

r? rust-lang/libs-api

@rustbot rustbot assigned dtolnay and unassigned BurntSushi Sep 24, 2023
@dtolnay dtolnay removed the T-libs Relevant to the library team, which will review and decide on the PR/issue. label Sep 24, 2023
Copy link
Member

@dtolnay dtolnay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about adjusting the trait bound on make_mut instead? It can be implemented the current way for T: Clone and separately for [T].

impl<T: CanMakeMut, A: Allocator + Clone> Arc<T, A> {
    pub fn make_mut(this: &mut Self) -> &mut T { ... }
}

impl<T: Clone> CanMakeMut for T { ... }

impl<T: Clone> CanMakeMut for [T] { ... }

@kpreid
Copy link
Contributor Author

kpreid commented Sep 24, 2023

This is insta-stable, so it needs libs-api FCP.

Is it? The current commit only adds unstable inherent methods. There's no trait implementation involved.

How about adjusting the trait bound on make_mut instead?

I like that idea much better since it doesn't add a new name. (Though it would be insta-stable.) I'm not familiar with how introducing a trait like CanMakeMut should work in std; should the trait be (perma?-)unstable or public-in-private sealed?

Actually, the trait could be of more broad use — it seems like it could be a general "clone ?Sized into uninit", which suggests it should be an unstable trait not tied to Rc/Arc in particular. So maybe it becomes core::mem::CloneUnsized or something like that? Is there any existing work on unsized rvalues that has such a trait?

@thomcc
Copy link
Member

thomcc commented Sep 24, 2023

Oh, it's totally not insta-stable, my bad (sorry, been a draining couple of weeks for me).

Still, I'll leave the review to the assignee at this point.

@dtolnay
Copy link
Member

dtolnay commented Sep 24, 2023

The core::clone module has been looking pretty bare for a decade. 🥳

I would definitely be on board with a trait that allows cloning into a pre-allocated &mut MaybeUninit<Self>. I think it would need to be unsafe trait, right? The calling code needs to be able to do assume_init afterwards without the possibility that the trait impl didn't actually initialize the thing.

I am not familiar with the Rc and Arc code but if such a trait existed, would it be straightforward for their make_mut to allocate a value of size header + mem::size_of_val(&**self), cast the spot for the value to &mut MaybeUninit<T>, and call the CloneUnsized to get the value cloned into there?

@kpreid
Copy link
Contributor Author

kpreid commented Sep 24, 2023

Observation: The new CloneToUninit trait turns out to be identical in signature to the internal trait alloc::alloc::WriteCloneIntoRaw, except for the ?Sizedness. That's a good sign, I think — I'm refining something that already proved useful rather than making up an ad-hoc solution.

@kpreid
Copy link
Contributor Author

kpreid commented Sep 24, 2023

Observation: It's not possible to define these operations in terms of MaybeUninit<T> (as Rc currently does inside maek_mut(), and a previous comment suggested), because MaybeUninit<T> requires T: Sized, so you cannot have a MaybeUninit<T> where T might be [U]. I wonder if changing that would help all maybe-unsized code — but presumably it's difficult, and certainly out of scope for this PR.

@rust-log-analyzer

This comment has been minimized.

@kpreid
Copy link
Contributor Author

kpreid commented Sep 25, 2023

It was quite an adventure, but I believe I've got it all set now. I had to introduce additional helper types at both the CloneToUninit layer and the make_mut() layer in order to avoid leaks on panic.

Note that make_mut()'s enlarged receiver type bounds are insta-stable. Additionally, you can tell that CloneToUninit is specialized in the documentation, but I assume that's fine because it doesn't affect which programs will compile.

@kpreid kpreid changed the title Add {Rc, Arc}::make_mut_slice(). Generalize {Rc,Arc}::make_mut() to unsized types. Sep 25, 2023
@kpreid
Copy link
Contributor Author

kpreid commented Sep 25, 2023

Updated PR description with the new design based on CloneToUninit.

@kpreid kpreid requested a review from dtolnay September 25, 2023 01:03
@rust-log-analyzer

This comment has been minimized.

@dtolnay
Copy link
Member

dtolnay commented Jun 22, 2024

@bors r+

@bors
Copy link
Collaborator

bors commented Jun 22, 2024

📌 Commit 88c3db5 has been approved by dtolnay

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 22, 2024
@bors
Copy link
Collaborator

bors commented Jun 22, 2024

⌛ Testing commit 88c3db5 with merge f944afe...

@bors
Copy link
Collaborator

bors commented Jun 22, 2024

☀️ Test successful - checks-actions
Approved by: dtolnay
Pushing f944afe to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Jun 22, 2024
@bors bors merged commit f944afe into rust-lang:master Jun 22, 2024
@rustbot rustbot added this to the 1.81.0 milestone Jun 22, 2024
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (f944afe): comparison URL.

Overall result: ❌ regressions - ACTION NEEDED

Next Steps: If you can justify the regressions found in this perf run, please indicate this with @rustbot label: +perf-regression-triaged along with sufficient written justification. If you cannot justify the regressions please open an issue or create a new PR that fixes the regressions, add a comment linking to the newly created issue or PR, and then add the perf-regression-triaged label to this PR.

@rustbot label: +perf-regression
cc @rust-lang/wg-compiler-performance

Instruction count

This is a highly reliable metric that was used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
0.8% [0.3%, 2.2%] 13
Regressions ❌
(secondary)
0.9% [0.9%, 0.9%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 0.8% [0.3%, 2.2%] 13

Max RSS (memory usage)

Results (primary -5.7%, secondary -2.2%)

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-5.7% [-5.7%, -5.7%] 1
Improvements ✅
(secondary)
-2.2% [-2.2%, -2.2%] 1
All ❌✅ (primary) -5.7% [-5.7%, -5.7%] 1

Cycles

This benchmark run did not return any relevant results for this metric.

Binary size

Results (primary 0.1%, secondary 0.3%)

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
0.2% [0.1%, 0.3%] 8
Regressions ❌
(secondary)
0.3% [0.3%, 0.3%] 1
Improvements ✅
(primary)
-0.1% [-0.1%, -0.0%] 7
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 0.1% [-0.1%, 0.3%] 15

Bootstrap: 694.577s -> 694.429s (-0.02%)
Artifact size: 327.03 MiB -> 326.84 MiB (-0.06%)

@rustbot rustbot added the perf-regression Performance regression. label Jun 22, 2024
@Mark-Simulacrum Mark-Simulacrum added the perf-regression-triaged The performance regression has been triaged. label Jun 23, 2024
@Mark-Simulacrum
Copy link
Member

Regressions are mostly in doc benchmarks, seem likely to be just new docs due to extra stuff in the standard library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. merged-by-bors This PR was explicitly merged by bors. perf-regression Performance regression. perf-regression-triaged The performance regression has been triaged. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. S-waiting-on-fcp Status: PR is in FCP and is awaiting for FCP to complete. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.