Deconstructing `Option` in const context
⚓ Rust 📅 2026-01-08 👤 surdeus 👁️ 4This doesn't compile:
const fn f<T>(slot: &mut MaybeUninit<T>, value: Option<T>) {
if let Some(value) = value {
// use value somehow
slot.write(value);
}
}
error[E0493]: destructor of `Option<T>` cannot be evaluated at compile-time
--> src/lib.rs:38:42
|
38 | const fn f<T>(slot: &mut MaybeUninit<T>, value: Option<T>) {
| ^^^^^ the destructor for this type cannot be evaluated in constant functions
We can unsafely duplicate T if the value is Some<T>, and forget the Option<T> to make the compiler happy:
const fn f<T>(slot: &mut MaybeUninit<T>, value: Option<T>) {
if let Some(value) = value.as_ref() {
let value = unsafe { std::ptr::read(value) };
// use value somehow
slot.write(value);
}
std::mem::forget(value);
}
However, depending on what you do with the value a panic could cause a double free. So I thought let's forget the value first:
const fn option_manually_drop<T>(value: Option<T>) -> Option<std::mem::ManuallyDrop<T>> {
let out = match value.as_ref() {
Some(v) => Some(std::mem::ManuallyDrop::new(unsafe { std::ptr::read(v) })),
None => None,
};
std::mem::forget(value);
out
}
const fn f<T>(slot: &mut MaybeUninit<T>, value: Option<T>) {
if let Some(value) = option_manually_drop(value) {
let value = std::mem::ManuallyDrop::into_inner(value);
// use value somehow
slot.write(value);
}
}
Am I overcomplicating this? Is there a better solution/implementation?
2 posts - 1 participant
🏷️ Rust_feed