Skip to content

stabilize Box::take - #160436

Merged
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
edwloef:stabilize-box-take
Sep 23, 2026
Merged

rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
edwloef:stabilize-box-take

Conversation

@edwloef

@edwloef edwloef commented Aug 3, 2026 •

Copy link
Copy Markdown
Contributor

View all comments

Tracking issue: #147212

There hasn't been any activity on the tracking issue for a while, and this is a pretty small feature, so opening this to hopefully get a FCP started.

Closes: #147212

@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 Aug 3, 2026
@rustbot

rustbot commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

r? @Darksonn

rustbot has assigned @Darksonn.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: libs
  • libs expanded to 12 candidates
  • Random selection from 6 candidates

@edwloef edwloef mentioned this pull request Aug 3, 2026
4 tasks
@Darksonn

Darksonn commented Aug 3, 2026

Copy link
Copy Markdown
Member

@rustbot label +I-libs-api-nominated

@rustbot rustbot added the I-libs-api-nominated [DEPRECATED; DO NOT USE] label Aug 3, 2026
@Darksonn Darksonn added needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. S-waiting-on-t-libs-api [DEPRECATED; DO NOT USE] and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 3, 2026
@Amanieu

Amanieu commented Aug 4, 2026

Copy link
Copy Markdown
Member

@rfcbot merge libs-api

@rust-rfcbot

rust-rfcbot commented Aug 4, 2026 •

Copy link
Copy Markdown
Collaborator

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

No concerns currently listed.

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. and removed needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. labels Aug 4, 2026
@Amanieu Amanieu added 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. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. and removed 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. I-libs-api-nominated [DEPRECATED; DO NOT USE] needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. labels Aug 4, 2026
@nia-e nia-e added S-waiting-on-t-libs Status: Awaiting decision from T-libs and removed S-waiting-on-t-libs-api [DEPRECATED; DO NOT USE] labels Aug 10, 2026
@rust-rfcbot rust-rfcbot added the final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. label Aug 11, 2026
@rust-rfcbot

Copy link
Copy Markdown
Collaborator

🔔 This is now entering its final comment period, as per the review above. 🔔

@rust-rfcbot rust-rfcbot removed the proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. label Aug 11, 2026
@coolreader18

Copy link
Copy Markdown
Contributor

I wonder if there might be a better name - currently in the standard library, take means either "given a reference, replace with Default::default() and return value" (Option::take, mem::take, RefCell::take) or "limit the number of items in this stream" (Iterator::take, io::Read::take). This is definitely a variant of the former, but it takes by value and returns a different type. I think it would be reached for in different situations (as an optimization, rather than for mutating data), and it's valuable to not overload the names of operations to reduce confusion. Perhaps a name that makes it clear this is reclaiming the allocation?

@edwloef

edwloef commented Aug 13, 2026 •

Copy link
Copy Markdown
Contributor Author

I like to think of the use of Box::take as a type-level Box<Option<T>>, where it would be the equivalent of taking the Some value out of that Option (and Box::write would be the equivalent of setting the option to a Some value). @camsteffen also noted in the tracking issue that "It fits the common semantic of removing a value from something", or written differently, taking a value out of something.

Box::read would be a nice parallel to both Box::write and ptr::read, but of course that's already taken by impl<R: Read> for Box<R>. Though that might be okay, since the signatures differ? At least Box::write is also present in triplicate thanks to impl<W: Write> Write for Box<W> and impl<T: Hasher> Hasher for Box<T>.

The other suggestion in the tracking issue was into_inner_and_uninit, but I dislike that because there's no precedent in the standard library for into_inner_and_*.

@ia0

ia0 commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

In that situation, we would end up losing either ability 1 or ability 2 from my list above (and ability 1 is this commit).

Indeed, I believe we should lose ability 2 from the list, because Box is different from &own. Box is not a reference, it always points to a full allocation.

That's a cross post from rust-lang/rfcs#4000 (comment).

@edwloef

edwloef commented Aug 23, 2026 •

Copy link
Copy Markdown
Contributor Author

My own opinion on this is that the property that should be dropped is 3, and that doing this should be allowed (and that converting enum fields to boxes should be interpreted as destructively destructuring the enum, so that it would not be expected to have a meaningful discriminant afterwards).

I agree. Sorry, misread, I would agree with dropping 2. It would make more sense to my mental model if a Box<T> owned its entire backing allocation, and not only the portion that contains valid bitpatterns of T. Even if not:

But some people have suggested that doing this sort of thing should produce a "typed MaybeUninit" that can only store bit patterns that are valid for the original type, rather than being able to store arbitrary data as well.

While this would be fine regarding this API, it would put Box::{map, try_map} (#144419) in jeopardy of being UB in the case where they don't reallocate (indeed, they are implemented internally via Box::take). Box::map is currently being stabilized as well: #160534.

@RalfJung

RalfJung commented Aug 23, 2026 •

Copy link
Copy Markdown
Member

Indeed, I believe we should lose ability 2 from the list, because Box is different from &own. Box is not a reference, it always points to a full allocation.

I agree. A Box<T, A> pointing to a field of an enum (or struct) is IMO a misuse of the Box API, we shouldn't use hacks like that. A full allocation is logically distinct from just any old block of memory.

@ais523

ais523 commented Aug 23, 2026

Copy link
Copy Markdown

A Box pointing to a struct field is entirely reasonable if you have a custom allocator. I've written such allocators myself (they store a struct on the stack as a source of memory, allocate from that, and move to the heap if they run out of space on the stack). (And a Box that uses a custom allocator is usually not returning full allocations.)

From my point of view, Box doesn't really have anything to do with the heap (the important properties of a Box from my point of view are that it owns a value and is able to return the contained memory so that it can be used for other purposes). As an example, the allocations that contain a function's local variables are as far as I can tell indistinguishable from a set of Boxes with a short-lived lifetime (they are allocated when the function starts running, deallocated when the function ends, and you can move out of them), and I would expect them to be modeled as boxes in formalizations like minirust.

@RalfJung

RalfJung commented Aug 23, 2026 •

Copy link
Copy Markdown
Member

A Box pointing to a struct field is entirely reasonable if you have a custom allocator. I've written such allocators myself (they store a struct on the stack as a source of memory, allocate from that, and move to the heap if they run out of space on the stack). (And a Box that uses a custom allocator is usually not returning full allocations.)

If the allocator does the work of ensuring that the field behaves like an allocation, then yes, it is.
But an allocator has to support arbitrary data being written into the memory it returns, and obviously that's not the case if you return a pointer into the field of an Option<bool>.


After a quick read of the mentioned RFC, I think that under my preferred interpretation of the safety contract for &own, there isn't even a problem here. We can have both Box::take and "&own-as-Box". Box and &own should have in common that it's fine to put arbitrary garbage data into them before doing a shallow drop.

@Amanieu Amanieu added the I-libs-nominated Nominated for discussion during a libs team meeting. label Aug 23, 2026
@Darksonn

Copy link
Copy Markdown
Member

I agree that 2 is to be dropped. It's misuse of box, and if we want &own, it can be a new type.

@joshtriplett

joshtriplett commented Aug 25, 2026 •

Copy link
Copy Markdown
Member

But an allocator has to support arbitrary data being written into the memory it returns, and obviously that's not the case if you return a pointer into the field of an Option<bool>.

You should not be able to get an &own T (or a Box<T, NoDeallocation>) from a T without consuming the T, so that you can't get the T back later in an invalid state. (Exceptions would be things like a MaybeUninit or similar type that is allowed to contain an invalid bit pattern.)

This is the same reason drop_in_place is unsafe. Being able to get an &own T from a T and later get the T back later after dropping the &own T would be equivalent to drop_in_place.

@nia-e nia-e removed the I-libs-nominated Nominated for discussion during a libs team meeting. label Sep 1, 2026
@edwloef

edwloef commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

Given that the stabilization of Box::map has been merged, I'll assume this is ready as well?

@clarfonthey clarfonthey added I-libs-nominated Nominated for discussion during a libs team meeting. and removed S-waiting-on-t-libs Status: Awaiting decision from T-libs labels Sep 13, 2026
@Darksonn

Copy link
Copy Markdown
Member

It looks like @Amanieu libs-nominated this for discussion, but then the label was lost. Did any further discussion occur / is it needed?

@programmerjake

Copy link
Copy Markdown
Member

My own opinion on this is that the property that should be dropped is 3

I think we should drop 3 (thereby allowing you to scribble over memory when/after dropping the T living there); I'm not sure about 2 (Box<T, NoOp<'_>> being interconvertible with &own T), though I don't think they should be the exact same type.

@Darksonn Darksonn 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 Sep 19, 2026
@nia-e nia-e removed the I-libs-nominated Nominated for discussion during a libs team meeting. label Sep 22, 2026
@nia-e

nia-e commented Sep 22, 2026

Copy link
Copy Markdown
Member

Apologies, we thought this got through to the relevant folks. Our conclusion was that we're fine with stabilising this as-is

@Darksonn

Copy link
Copy Markdown
Member

@bors r+

@rust-bors

rust-bors Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

📌 Commit c918352 has been approved by Darksonn

It is now in the queue for this repository.

@rust-bors rust-bors Bot 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-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Sep 22, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Sep 22, 2026
…sonn

stabilize `Box::take`

Tracking issue: rust-lang#147212

There hasn't been any activity on the tracking issue for a while, and this is a pretty small feature, so opening this to hopefully get a FCP started.

Closes: rust-lang#147212
rust-bors Bot pushed a commit that referenced this pull request Sep 22, 2026
…uwer

Rollup of 13 pull requests

Successful merges:

 - #156949 (Detect missing else in let statement)
 - #160436 (stabilize `Box::take`)
 - #160570 (macro_metavar_expr_concat: support concatenating into string literals)
 - #162837 (Dedicated Display type for CStr::display)
 - #163099 (Use wrapping arithmetic in `from_str_radix`)
 - #163166 (Tiny cleanups to deferred liveness)
 - #161667 (Add `f16` inline ASM support for `nvptx64-nvidia-cuda`)
 - #163063 (Restore `Send` and `Sync` for `BorrowedCursor`)
 - #163097 (OpenBSD/sparc64 has switched from GCC to Clang)
 - #163126 (Skip redundant storage-conflict updates during coroutine layout)
 - #163135 (librustdoc: remove stale dep on base64)
 - #163146 (tests: Update `f16b` codegen test for LoongArch and RISC-V)
 - #163159 (treat inductive cycles as ambig)
@rust-bors
rust-bors Bot merged commit 1b7b9ea into rust-lang:main Sep 23, 2026
13 checks passed
@rustbot rustbot added this to the 1.100.0 milestone Sep 23, 2026
rust-bors Bot pushed a commit that referenced this pull request Sep 23, 2026
Rollup merge of #160436 - edwloef:stabilize-box-take, r=Darksonn

stabilize `Box::take`

Tracking issue: #147212

There hasn't been any activity on the tracking issue for a while, and this is a pretty small feature, so opening this to hopefully get a FCP started.

Closes: #147212
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. finished-final-comment-period The final comment period is finished for this PR / Issue. 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. to-announce Announce this issue on triage meeting

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tracking Issue for Box::take