alloc/collections/btree/mem.rs
1use core::{intrinsics, mem, ptr};
2
3/// This replaces the value behind the `v` unique reference by calling the
4/// relevant function.
5///
6/// If a panic occurs in the `change` closure, the entire process will be aborted.
7#[allow(dead_code)] // keep as illustration and for future use
8#[inline]
9pub(super) fn take_mut<T>(v: &mut T, change: impl FnOnce(T) -> T) {
10 replace(v, |value| (change(value), ()))
11}
12
13/// This replaces the value behind the `v` unique reference by calling the
14/// relevant function, and returns a result obtained along the way.
15///
16/// If a panic occurs in the `change` closure, the entire process will be aborted.
17#[inline]
18pub(super) fn replace<T, R>(v: &mut T, change: impl FnOnce(T) -> (T, R)) -> R {
19 let guard = mem::DropGuard::new((), |()| intrinsics::abort());
20 // SAFETY: v is valid for reads and we write a new value before returning.
21 let value = unsafe { ptr::read(v) };
22 let (new_value, ret) = change(value);
23 // SAFETY: new_value is T and v is valid for writes.
24 unsafe {
25 ptr::write(v, new_value);
26 }
27 mem::DropGuard::dismiss(guard);
28 ret
29}