Skip to content

Stabilize box_vec_non_null#157226

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

Stabilize box_vec_non_null#157226
theemathas wants to merge 1 commit into
rust-lang:mainfrom
theemathas:stab-box-vec-non-null

Conversation

@theemathas
Copy link
Copy Markdown
Contributor

@theemathas theemathas commented Jun 1, 2026

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) { .... }
    pub const fn as_non_null(&mut self) -> NonNull<T> { .... }
}

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). However, Vec::as_non_null will become const-stable (like Vec::as_ptr).

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) { .... }
}

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
Copy link
Copy Markdown

ds84182 commented Jun 1, 2026

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
Copy link
Copy Markdown
Member

nia-e commented Jun 2, 2026

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
Copy link
Copy Markdown
Collaborator

rust-rfcbot commented Jun 2, 2026

Team member @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
Copy link
Copy Markdown
Member

RalfJung commented Jun 2, 2026

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

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