Skip to content

Partially stabilize box_vec_non_null#157226

Open
theemathas wants to merge 3 commits into
rust-lang:mainfrom
theemathas:stab-box-vec-non-null
Open

Partially stabilize box_vec_non_null#157226
theemathas wants to merge 3 commits into
rust-lang:mainfrom
theemathas:stab-box-vec-non-null

Conversation

@theemathas

@theemathas theemathas commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Closes #130364

r? libs-api

What's being stabilized

The following is being stabilized in this PR:

impl<T: ?Sized> Box<T> {
    pub unsafe fn from_non_null(ptr: NonNull<T>) -> Self { .... }
}
impl<T: ?Sized, A: Allocator> Box<T, A> {
    pub fn into_non_null(b: Self) -> NonNull<T> { .... }
}
impl<T> Vec<T> {
    pub const unsafe fn from_parts(ptr: NonNull<T>, length: usize, capacity: usize) -> Self { .... }
}
impl<T, A: Allocator> Vec<T, A> {
    pub const fn into_parts(self) -> (NonNull<T>, usize, usize) { .... }
}

Note that Vec::from_parts and Vec::into_parts remain const-unstable behind the const_heap feature (like Vec::from_raw_parts and Vec::into_raw_parts).

The following APIs remain gated behind allocator_api

impl<T: ?Sized, A: Allocator> Box<T, A> {
    pub unsafe fn from_non_null_in(raw: NonNull<T>, alloc: A) -> Self { .... }
    pub fn into_non_null_with_allocator(b: Self) -> (NonNull<T>, A) { .... }
}
impl<T, A: Allocator> Vec<T, A> {
    pub const unsafe fn from_parts_in(ptr: NonNull<T>, length: usize, capacity: usize, alloc: A) -> Self { .... }
    pub const fn into_parts_with_alloc(self) -> (NonNull<T>, usize, usize, A) { .... }
}

The following API is split into a new unstable feature in #157843, and remains unstable:

impl<T, A: Allocator> Vec<T, A> {
    pub const fn as_non_null(&mut self) -> NonNull<T> { .... }
}

Implementation History

Most of this feature was ACP'ed in rust-lang/libs-team#418, and implemented in #130061. Vec::as_non_null was ACP'ed separately in rust-lang/libs-team#440, and implemented in #130624.

Potential issues

@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 Jun 1, 2026
@theemathas theemathas added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. I-libs-api-nominated Nominated for discussion during a libs-api team meeting. needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. and removed T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jun 1, 2026
@ds84182

ds84182 commented Jun 1, 2026

Copy link
Copy Markdown

An additional issue: Should Vec::into_parts return a struct with pub fields rather than a tuple? Having two usize tuple elements seems a bit error prone. Alternatively it could return (NonNull<[T]>, usize).

EDIT: It could also be (NonNull<[MaybeUninit<T>]>, usize), the pointer being the storage (ptr + cap) and the usize being the length.

@clarfonthey

Copy link
Copy Markdown
Contributor

Just cataloguing the similar methods from rustdoc:

from_raw_parts/slice_from_raw_parts

  • (*const T, usize) <-> &[T]
  • (*const u8, usize) <-> str (unstable)
  • (NonNull<T>, usize) <-> NonNull<[T]>

into_raw_parts/from_raw_parts

  • String <-> (*mut u8, usize, usize)
  • Vec<T> <-> (*mut T, usize, usize)'

from_parts/into_parts: (proposed)

  • Vec<T> <-> (NonNull<T>, usize, usize)

to_raw_parts/from_raw_parts (unstable)

  • *const T <-> (*const (), T::Metadata)
  • NonNull<T> <-> `(NonNull<()>, T::Metadata)

I think that (NonNull<T>, usize, usize) would be a good choice due to the analogy to from_raw_parts/into_raw_parts, but that maybe it should be named from_non_null_parts instead.

The only other methods in libstd that use the term "parts" are BufWriter::into_parts, returning (W, Result<Vec<u8>, WriterPanicked) and IntoInnerError::into_parts (returned by BufWriter::into_inner) which returns (Error, W). (yes, annoyingly, those are reversed.)

Would say that maybe we should not label any "parts" as canonical for now at least, since it's not clear what version would be best to use.

@nia-e

nia-e commented Jun 2, 2026

Copy link
Copy Markdown
Member

cc @rust-lang/opsem - is there a reason on your end to make as_non_null take a &mut instead of &? If not, we'd like to change it to & (same for rust-lang/libs-team#799). Otherwise, ready to open FCP on the other changes

@joshtriplett

Copy link
Copy Markdown
Member

Shall we stabilize these?

@rfcbot merge libs-api

@rfcbot concern as_non_null-shared-reference

@rust-rfcbot

rust-rfcbot commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

@joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members:

Concerns:

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rust-rfcbot rust-rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Jun 2, 2026
@RalfJung

RalfJung commented Jun 2, 2026

Copy link
Copy Markdown
Member

Which exact function is this about?

EDIT: I assume Vec::as_non_null. The outer reference doesn't affect the inner pointer in any of our current models, and I don't think it should. But we also have not conclusively ruled that out.

Though given that the returned pointer is meant to be mutable, my personal preference would be &mut self. We have repeatedly seen violations of shared reference immutability correlate with poor mutability discipline for raw pointers (const-to-mut-raw-ptr-cast is allowed but should be considered highly suspicious); I'd rather not see std proliferate patterns of that sort.

@BurntSushi

Copy link
Copy Markdown
Member

I like these. I'm concerned about the from_parts and into_parts naming though. It suggests, to me, that these are the canonical "parts" of a Vec, and it's not clear to me that's true. I think I'd rather see from_non_null_parts and into_non_null_parts. It also matches the naming convention used for the rest of the methods.

@rfcbot concern from_parts and into_parts naming

@theemathas

Copy link
Copy Markdown
Contributor Author

Just to confirm: T-libs-api has agreed to stabilize with the name non_null, and not nonnull, right? The meeting notes didn't mention this.

@BurntSushi The reason the Vec functions were named with parts was due to a libs-api request. Has the consensus on the best name changed since then?

@BurntSushi

Copy link
Copy Markdown
Member

@theemathas Not sure if anything has changed or if it has been discussed. That comment is from almost 2 years ago though. @joshtriplett Thoughts on the naming here?

@nia-e

nia-e commented Jun 3, 2026

Copy link
Copy Markdown
Member

Just to confirm: T-libs-api has agreed to stabilize with the name non_null, and not nonnull, right? The meeting notes didn't mention this.

I think we have generally agreed in the past that non-null is non_null. we kept the contracted form only for nonzero.

@nia-e

nia-e commented Jun 12, 2026

Copy link
Copy Markdown
Member

To resolve the & vs &mut concern, we decided in this week's libs-api meeting to defer stabilising as_non_null for now. The rest of the methods can get stabilised here as-is. cc @joshtriplett as you raised the concern

@theemathas

theemathas commented Jun 13, 2026

Copy link
Copy Markdown
Contributor Author

@nia-e I assume this also means:

  • from_parts and into_parts are to be stabilized as-is.
  • It's spelled non_null and not nonnull

@theemathas theemathas force-pushed the stab-box-vec-non-null branch from 24e92dc to a18a972 Compare June 13, 2026 02:23
@rustbot

rustbot commented Jun 13, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@theemathas theemathas changed the title Stabilize box_vec_non_null Partially stabilize box_vec_non_null Jun 13, 2026
@theemathas

Copy link
Copy Markdown
Contributor Author

I've updated the PR and the PR description, so Vec::as_non_null() will not be stabilized in this PR.

@nia-e nia-e removed the I-libs-api-nominated Nominated for discussion during a libs-api team meeting. label Jun 16, 2026
@theemathas

Copy link
Copy Markdown
Contributor Author

@BurntSushi @joshtriplett May the concerns be resolved?

@BurntSushi

Copy link
Copy Markdown
Member

I don't think my concern has been addressed. Like, from_parts/into_parts implies a level of canonical-ness that isn't obviously warranted to me. We already have from_raw_parts/into_raw_parts, so I think we should just go with from_non_null_parts/into_non_null_parts. This leaves the door open for other routines in the future, e.g., using Box<[MaybeUninit]> as noted in the OP.

I also don't think these routines are used enough to warrant the shorter name.

@theemathas theemathas added the I-libs-api-nominated Nominated for discussion during a libs-api team meeting. label Jun 20, 2026
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. I-libs-api-nominated Nominated for discussion during a libs-api team meeting. needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. 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.

Tracking Issue for box_vec_non_null

10 participants