Skip to content

Box::take for taking the value out of a box without deallocating it #663

@edwloef

Description

@edwloef

Proposal

Problem statement

There's no provided way of taking the value out of a box without also deallocating the heap memory it owns. This could be useful to either defer deallocation to some other point in time, or to deallocate on a different thread, or to reuse that allocation for another boxed value (using Box::write).

Motivating examples or use cases

In message-oriented applications it's a fairly common practice to minimize the message enum type's size by boxing very large variants (see clippy::large_enum_variant). However, this currently isn't easily usable in realtime-constrained situations. A usecase could look like this:

enum RealtimeMessage {
    VeryLarge(Box<VeryLarge>),
    ...
}

enum NonRealtimeMessage {
    Deallocate(Box<MaybeUninit<VeryLarge>>),
    ...
}

match consumer.pop() {
    RealtimeMessage::VeryLarge(very_large) => {
        let (very_large, uninit) = Box::take(very_large);
        producer.push(NonRealtimeMessage::Deallocate(uninit));
        ...
    }
    ...
}

Solution sketch

impl<T> Box<T> {
    pub fn take(boxed: Box<T>) -> (T, Box<MaybeUninit<T>>);
}

Alternatives

  • don't box the value
  • a Vec<T> with one item
  • Box<Option<T>> and Option::take
  • Box<MaybeUninit<T>> and MaybeUninit::assume_init_read
  • Box<ManuallyDrop<T>> and ManuallyDrop::take

Metadata

Metadata

Assignees

No one assigned

    Labels

    ACP-acceptedAPI Change Proposal is accepted (seconded with no objections)T-libs-apiapi-change-proposalA proposal to add or alter unstable APIs in the standard libraries

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions