Skip to content
New issue

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

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

Already on GitHub? # 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
@zachs18 zachs18 force-pushed the rc-into-raw-with-allocator branch from 2134c8e to c412131 Compare February 10, 2024 05:30
@zachs18 zachs18 force-pushed the rc-into-raw-with-allocator branch from 888f0cf to 5a23ea9 Compare February 19, 2024 05:42
@rust-log-analyzer

This comment has been minimized.

@zachs18 zachs18 force-pushed the rc-into-raw-with-allocator branch from 5a23ea9 to c3136d9 Compare February 19, 2024 05:53
@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
@zachs18 zachs18 force-pushed the rc-into-raw-with-allocator branch from c3136d9 to d86ce86 Compare April 12, 2024 17:41
@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.

zachs18 added 5 commits April 29, 2024 18:08
* 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 zachs18 force-pushed the rc-into-raw-with-allocator branch from d86ce86 to 9f3dc91 Compare April 29, 2024 23:10
@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
# for free to join this conversation on GitHub. Already have an account? # 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