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

Make (A)Rc/Weak allocator_api APIs more consistent #119761

Closed
wants to merge 6 commits into from

Conversation

zachs18
Copy link
Contributor

@zachs18 zachs18 commented Jan 9, 2024

Make Arc/sync::Weak/Rc/rc::Weak unstable feature(allocator_api) APIs more consistent with other containers (well, Box), and with each other.

  1. fn into_raw_with_allocator for all.
    • 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 Weaks.
  2. fn allocator for all.
    • For Rc/Arc, the existing associated fns are changed to allow unsized pointees.
    • For Weaks, methods are added.
  3. Remove where A: Clone bound on (stable) Rc::downcast and downcast_unchecked, (unstable) assume_inits, and some (stable) trait impls
    • (Arc::{downcast{,_unchecked}, assume_init} were changed by Fix some Arc allocator leaks #120445)
    • downcast(_unchecked) and assume_init semantically should not require cloning the allocator; they are essentially just ((un)checked) pointer casts.
    • Remove A: Clone bound from From<Vec<T, A>> for Arc<[T], A> (Rc's already didn't have a A: Clone bound) and TryFrom<Arc<[T], A>> for Arc<[T; N], A> (done by Fix some Arc allocator leaks #120445) (see below for Rc)
  4. Make TryFrom<Rc<[T]>> for Rc<[T; N]> allocator-aware.

This is adding 61 new unstable functions, changing the bounds on 6 3 unstable functions, and changing the (unstable) bounds on 7 5 stable functions, so I think it needs at least a libs-api FCP? If it also needs an ACP I can make one. (If the parts of this PR should be split I can do that too.)

@rustbot label +A-allocators +T-libs-api -T-libs

Future PR

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
Vec any allocator allocator is forgotten
Arc/Rc/Weak any allocator allocator is forgotten(Arc) (sync::Weak) (Rc) (rc::Weak)

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)

Footnotes

  1. Technically 5 new and 1 renamed, since rc::Weak::into_raw_with_allocator is not newly added, as it was modified and renamed from rc::Weak::into_raw_and_alloc.

@rustbot
Copy link
Collaborator

rustbot commented Jan 9, 2024

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. A-allocators Area: Custom and system allocators T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Jan 9, 2024
@rust-log-analyzer

This comment has been minimized.

@zachs18
Copy link
Contributor Author

zachs18 commented Jan 9, 2024

@rustbot label -T-libs

r? rust-lang/libs-api

@rustbot rustbot removed the T-libs Relevant to the library team, which will review and decide on the PR/issue. label Jan 9, 2024
@rustbot rustbot assigned BurntSushi and unassigned thomcc Jan 9, 2024
@bors
Copy link
Contributor

bors commented Jan 30, 2024

☔ The latest upstream changes (presumably #120496) made this pull request unmergeable. Please resolve the merge conflicts.

@zachs18

This comment was marked as resolved.

@rustbot rustbot 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 Feb 10, 2024
@rust-log-analyzer

This comment has been minimized.

@zachs18
Copy link
Contributor Author

zachs18 commented Feb 19, 2024

@rustbot ready

@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 Feb 19, 2024
@bors
Copy link
Contributor

bors commented Apr 27, 2024

☔ The latest upstream changes (presumably #124432) made this pull request unmergeable. Please resolve the merge conflicts.

* Add `into_raw_with_allocator` on `Rc`/`Weak`
* Remove `where A: Clone` from `Rc::assume_init`s, `Rc::unwrap_or_clone`, and `Rc::downcast(_unchecked)`
* Add `fn allocator(&self)` to `Rc`/`Weak` for all `T: ?Sized`
* Make `TryFrom<Rc<[T]>> for Rc<[T; N]>` allocator-aware
@zachs18
Copy link
Contributor Author

zachs18 commented May 1, 2024

@BurntSushi Friendly ping (I just realized that the r? libs-api probably didn't send a notification)

@BurntSushi
Copy link
Member

I'm not really dialed into the allocator work. Can you find someone who is to review this? Maybe @matthieu-m?

@BurntSushi
Copy link
Member

Alternatively, if this PR can be split up into more digestible chunks, that might help get it reviewed more quickly.

@matthieu-m
Copy link
Contributor

@BurntSushi From what I can tell, this PR does not require any Allocator specific knowledge, it doesn't actually even introduce any call Allocator methods (it eliminates calls to clone).

I think any libs member comfortable with API requests can tackle this review without issue.

(I'm neither a libs member, nor am I well-versed in API guidelines)

@zachs18
Copy link
Contributor Author

zachs18 commented May 2, 2024

I'll probably go ahead and split this into multiple PRs then. I probably won't have time to work on that for a week or so, so I'll leave this open if someone wants to reveiw it until then.

@zachs18
Copy link
Contributor Author

zachs18 commented May 10, 2024

Split into #124980 and #124981. Later PR will add fn into_raw_with_allocator.

@zachs18 zachs18 closed this May 10, 2024
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request May 11, 2024
… r=Mark-Simulacrum

Relax allocator requirements on some Rc/Arc APIs.

Split out from rust-lang#119761

* Remove `A: Clone` bound from `Rc::assume_init`(s), `Rc::downcast`, and `Rc::downcast_unchecked` (`Arc` methods were already relaxed by rust-lang#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`.
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request May 11, 2024
… r=Mark-Simulacrum

Relax allocator requirements on some Rc/Arc APIs.

Split out from rust-lang#119761

* Remove `A: Clone` bound from `Rc::assume_init`(s), `Rc::downcast`, and `Rc::downcast_unchecked` (`Arc` methods were already relaxed by rust-lang#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`.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request May 11, 2024
… r=Mark-Simulacrum

Relax allocator requirements on some Rc/Arc APIs.

Split out from rust-lang#119761

* Remove `A: Clone` bound from `Rc::assume_init`(s), `Rc::downcast`, and `Rc::downcast_unchecked` (`Arc` methods were already relaxed by rust-lang#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`.
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request May 12, 2024
Rollup merge of rust-lang#124981 - zachs18:rc-allocator-generalize-1, r=Mark-Simulacrum

Relax allocator requirements on some Rc/Arc APIs.

Split out from rust-lang#119761

* Remove `A: Clone` bound from `Rc::assume_init`(s), `Rc::downcast`, and `Rc::downcast_unchecked` (`Arc` methods were already relaxed by rust-lang#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`.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request May 20, 2024
…-only, r=Mark-Simulacrum

Add `fn into_raw_with_allocator` to Rc/Arc/Weak.

Split out from rust-lang#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`.
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request May 20, 2024
Rollup merge of rust-lang#125093 - zachs18:rc-into-raw-with-allocator-only, r=Mark-Simulacrum

Add `fn into_raw_with_allocator` to Rc/Arc/Weak.

Split out from rust-lang#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`.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jul 12, 2024
Generalize `fn allocator` for Rc/Arc.

Split out from rust-lang#119761

- For `Rc`/`Arc`, the existing associated `fn`s are changed to allow unsized pointees.
 - For `Weak`s, new methods are added.

`@rustbot` label +A-allocators
workingjubilee added a commit to workingjubilee/rustc that referenced this pull request Jul 12, 2024
Generalize `fn allocator` for Rc/Arc.

Split out from rust-lang#119761

- For `Rc`/`Arc`, the existing associated `fn`s are changed to allow unsized pointees.
 - For `Weak`s, new methods are added.

``@rustbot`` label +A-allocators
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jul 12, 2024
Generalize `fn allocator` for Rc/Arc.

Split out from rust-lang#119761

- For `Rc`/`Arc`, the existing associated `fn`s are changed to allow unsized pointees.
 - For `Weak`s, new methods are added.

```@rustbot``` label +A-allocators
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jul 12, 2024
Generalize `fn allocator` for Rc/Arc.

Split out from rust-lang#119761

- For `Rc`/`Arc`, the existing associated `fn`s are changed to allow unsized pointees.
 - For `Weak`s, new methods are added.

````@rustbot```` label +A-allocators
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jul 12, 2024
Generalize `fn allocator` for Rc/Arc.

Split out from rust-lang#119761

- For `Rc`/`Arc`, the existing associated `fn`s are changed to allow unsized pointees.
 - For `Weak`s, new methods are added.

`````@rustbot````` label +A-allocators
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Jul 12, 2024
Rollup merge of rust-lang#124980 - zachs18:rc-allocator, r=Amanieu

Generalize `fn allocator` for Rc/Arc.

Split out from rust-lang#119761

- For `Rc`/`Arc`, the existing associated `fn`s are changed to allow unsized pointees.
 - For `Weak`s, new methods are added.

`````@rustbot````` label +A-allocators
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-allocators Area: Custom and system allocators S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. 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.

7 participants