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

Fix #124275: Implemented Default for Arc<str> #124640

Merged
merged 3 commits into from
May 19, 2024

Conversation

Billy-Sheppard
Copy link
Contributor

@Billy-Sheppard Billy-Sheppard commented May 3, 2024

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 #124367 (comment).

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?

@rustbot
Copy link
Collaborator

rustbot commented May 3, 2024

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @Mark-Simulacrum (or someone else) some time within the next two weeks.

Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (S-waiting-on-review and S-waiting-on-author) stays updated, invoking these commands when appropriate:

  • @rustbot author: the review is finished, PR author should check the comments and take action accordingly
  • @rustbot review: the author is ready for a review, this PR will be queued again in the reviewer's queue

@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 May 3, 2024
@rust-log-analyzer

This comment has been minimized.

@zachs18
Copy link
Contributor

zachs18 commented May 3, 2024

I think the stable attributes should probably be something like #[stable(feature = "more_rc_default_impls", since = "CURRENT_RUSTC_VERSION")], (literally CURRENT_RUSTC_VERSION, it will be replaced with 1.XX when 1.XX branches (e.g.)).

@rust-log-analyzer

This comment has been minimized.

@Mark-Simulacrum Mark-Simulacrum added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 4, 2024
@Billy-Sheppard
Copy link
Contributor Author

#124367 (comment)

As per this comment, I've removed the OsStr impls.

@rust-log-analyzer

This comment has been minimized.

@Billy-Sheppard Billy-Sheppard marked this pull request as ready for review May 6, 2024 07:43
@rustbot rustbot added the has-merge-commits PR has merge commits, merge with caution. label May 6, 2024
@rustbot
Copy link
Collaborator

rustbot commented May 6, 2024

There are merge commits (commits with multiple parents) in your changes. We have a no merge policy so these commits will need to be removed for this pull request to be merged.

You can start a rebase with the following commands:

$ # rebase
$ git rebase -i master
$ # delete any merge commits in the editor that appears
$ git push --force-with-lease

The following commits are merge commits:

@rustbot
Copy link
Collaborator

rustbot commented May 6, 2024

There are merge commits (commits with multiple parents) in your changes. We have a no merge policy so these commits will need to be removed for this pull request to be merged.

You can start a rebase with the following commands:

$ # rebase
$ git rebase -i master
$ # delete any merge commits in the editor that appears
$ git push --force-with-lease

The following commits are merge commits (since this message was last posted):

@rustbot
Copy link
Collaborator

rustbot commented May 6, 2024

There are merge commits (commits with multiple parents) in your changes. We have a no merge policy so these commits will need to be removed for this pull request to be merged.

You can start a rebase with the following commands:

$ # rebase
$ git rebase -i master
$ # delete any merge commits in the editor that appears
$ git push --force-with-lease

The following commits are merge commits (since this message was last posted):

@rustbot rustbot removed the has-merge-commits PR has merge commits, merge with caution. label May 6, 2024
@Billy-Sheppard
Copy link
Contributor Author

@rustbot review

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 7, 2024
@Billy-Sheppard
Copy link
Contributor Author

This PR is now the main solution for #124275

@Mark-Simulacrum
Copy link
Member

Hm, I see that there was an FCP in #124367 (comment) for these APIs, but I'm wondering if there was discussion already on whether these should return new Arc's or a shared Arc for the type (e.g., Arc with an empty string can share a single static, rather than having to allocate each time).

r? @dtolnay to make the decision whether to re-evaluate FCP or not (just random roll for libs-api)

@rustbot rustbot assigned dtolnay and unassigned Mark-Simulacrum May 11, 2024
@zachs18
Copy link
Contributor

zachs18 commented May 11, 2024

Regarding returning new vs shared Arcs, I think the docs could perhaps be updated to say something like

impl Default for (A)Rc<...> {
    /// Creates an empty ... inside an `(A)Rc`.
    ///
    /// This may or may not share an allocation with other `(A)Rc`s (on the same thread (for `Rc`)).
    fn default() -> Self { ... }
}

with the "may or may not" giving wiggle-room to add the "single shared allocation" semantics later (or to decide against it), but without blocking the impls on implementing those semantics now (It'd be doable for the concrete types Arc<str>/Arc<CStr>/etc, but it would be harder to do for Arc<[T]>1 or any Rc<...>2, and also harder to justify the cost).

Footnotes

  1. I have some rough draft code that implements the shared allocation semantics for Arc<[T]>, but it wouldn't work in alloc because it uses RwLock which is from std. The concrete type impls could probably just use an AtomicPtr each though, which is available in core.

  2. The Rc impls in my code require thread_local!s, as I think any implementation would, so I don't see a way to include any of those in alloc. #[thread_local] is IIUC not available on every platform3.

  3. Though I guess if we have the "may or may not" verbiage, then it could be platform-dependent whether or not the single-shared-allocation semantics are implemented.

@Mark-Simulacrum
Copy link
Member

I would expect that a shared allocation would use something like the static empty groups in hashbrown. For str for example we'd just have the strong + weak count header in a static EMPTY: Rc/ArcInner<()> or similar, and return EMPTY.clone() from these functions. (Some care would need to be taken to ensure that std itself "owns" one of the reference counts at all times, but that seems easy enough.)

@zachs18
Copy link
Contributor

zachs18 commented May 11, 2024

I hadn't thought of that, but yeah having a static ArcInner<_> would be a much simpler solution than lazily-initailizing a shared pointer. to a dynamic allocation. That also makes it simpler to do for [T], since we can just have a shared static for each alignment up to some threshold, and do the current make-a-new-allocation-on-each-call for anything over-aligned.

@Billy-Sheppard I have a branch with these changes if you'd like to incorporate them into this PR, or perhaps just the first commit with the documentation, and I can submit the implementation as a later PR.

@rustbot rustbot added the has-merge-commits PR has merge commits, merge with caution. label May 12, 2024
@Billy-Sheppard
Copy link
Contributor Author

I forgot to push my amended message, unfortunately the broken merge will still show in the PR comments here (apologies for all those that got pinged, I hadn't realised the merge didn't grab the current upstream.

@zachs18

This comment was marked as resolved.

@Billy-Sheppard
Copy link
Contributor Author

Ah yes I was wondering about that (attributing).

Good call

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.

Thanks!

I would be interested to review a followup PR that makes these share the same static ArcInner, instead of 6 different effectively-identical ones. The representation I would expect is a 16-byte-aligned static with the following contents:

+---------------+---------------+-+-----------------------------+
| strong count  |  weak count   |0|          padding            |
+---------------+---------------+-+-----------------------------+

This works as the ArcInner<[T]> for any align_of::<T>() <= 16, and also str and CStr.

@dtolnay dtolnay removed A-testsuite Area: The testsuite used to check the correctness of rustc O-macos Operating system: macOS T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-infra Relevant to the infrastructure team, which will review and decide on the PR/issue. T-release Relevant to the release subteam, which will review and decide on the PR/issue. A-meta Area: Issues & PRs about the rust-lang/rust repository itself A-query-system Area: The rustc query system (https://rustc-dev-guide.rust-lang.org/query.html) O-unix Operating system: Unix-like PG-exploit-mitigations Project group: Exploit mitigations WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels May 18, 2024
@dtolnay
Copy link
Member

dtolnay commented May 19, 2024

@bors r+

@bors
Copy link
Contributor

bors commented May 19, 2024

📌 Commit f27d1e1 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-review Status: Awaiting review from the assignee but also interested parties. labels May 19, 2024
@bors
Copy link
Contributor

bors commented May 19, 2024

⌛ Testing commit f27d1e1 with merge 496f731...

@bors
Copy link
Contributor

bors commented May 19, 2024

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

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label May 19, 2024
@bors bors merged commit 496f731 into rust-lang:master May 19, 2024
7 checks passed
@rustbot rustbot added this to the 1.80.0 milestone May 19, 2024
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (496f731): comparison URL.

Overall result: ✅ improvements - no action needed

@rustbot label: -perf-regression

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
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-0.2% [-0.2%, -0.2%] 1
All ❌✅ (primary) - - 0

Max RSS (memory usage)

Results (primary -2.5%, secondary -2.6%)

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)
-2.5% [-2.5%, -2.5%] 1
Improvements ✅
(secondary)
-2.6% [-2.7%, -2.4%] 2
All ❌✅ (primary) -2.5% [-2.5%, -2.5%] 1

Cycles

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

Binary size

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

Bootstrap: 670.24s -> 668.657s (-0.24%)
Artifact size: 316.18 MiB -> 316.06 MiB (-0.04%)

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request May 20, 2024
Use a single static for all default slice Arcs.

Also adds debug_asserts in Drop for Weak/Arc that the shared static is not being "dropped"/"deallocated".

As per rust-lang#124640 (review)

r? dtolnay
fmease added a commit to fmease/rust that referenced this pull request May 20, 2024
Use a single static for all default slice Arcs.

Also adds debug_asserts in Drop for Weak/Arc that the shared static is not being "dropped"/"deallocated".

As per rust-lang#124640 (review)

r? dtolnay
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request May 20, 2024
Use a single static for all default slice Arcs.

Also adds debug_asserts in Drop for Weak/Arc that the shared static is not being "dropped"/"deallocated".

As per rust-lang#124640 (review)

r? dtolnay
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request May 20, 2024
Rollup merge of rust-lang#125283 - zachs18:arc-default-shared, r=dtolnay

Use a single static for all default slice Arcs.

Also adds debug_asserts in Drop for Weak/Arc that the shared static is not being "dropped"/"deallocated".

As per rust-lang#124640 (review)

r? dtolnay
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants