Skip to content
13 changes: 11 additions & 2 deletions cranelift/entity/src/packed_option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
//! This module provides a `PackedOption<T>` for types that have a reserved value that can be used
//! to represent `None`.

use core::fmt;
use core::mem;
use core::{fmt, mem};
use wasmtime_core::{alloc::TryClone, error::OutOfMemory};

#[cfg(feature = "enable-serde")]
use serde_derive::{Deserialize, Serialize};
Expand All @@ -30,6 +30,15 @@ pub trait ReservedValue {
#[repr(transparent)]
pub struct PackedOption<T: ReservedValue>(T);

impl<T> TryClone for PackedOption<T>
where
T: ReservedValue + TryClone,
{
fn try_clone(&self) -> Result<Self, OutOfMemory> {
Ok(Self(self.0.try_clone()?))
}
}

impl<T: ReservedValue> PackedOption<T> {
/// Returns `true` if the packed option is a `None` value.
pub fn is_none(&self) -> bool {
Expand Down
35 changes: 35 additions & 0 deletions crates/core/src/alloc/try_clone.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::error::OutOfMemory;
use core::mem;
use std_alloc::sync::Arc;

/// A trait for values that can be cloned, but contain owned, heap-allocated
/// values whose allocations may fail during cloning.
Expand Down Expand Up @@ -39,6 +40,40 @@ where
}
}

impl<T, E> TryClone for Result<T, E>
where
T: TryClone,
E: TryClone,
{
#[inline]
fn try_clone(&self) -> Result<Self, OutOfMemory> {
match self {
Ok(x) => Ok(Ok(x.try_clone()?)),
Err(e) => Ok(Err(e.try_clone()?)),
}
}
}

impl<T> TryClone for Option<T>
where
T: TryClone,
{
#[inline]
fn try_clone(&self) -> Result<Self, OutOfMemory> {
match self {
Some(x) => Ok(Some(x.try_clone()?)),
None => Ok(None),
}
}
}

impl<T> TryClone for Arc<T> {
#[inline]
fn try_clone(&self) -> Result<Self, OutOfMemory> {
Ok(self.clone())
}
}

macro_rules! impl_try_clone_via_clone {
( $( $ty:ty ),* $(,)? ) => {
$(
Expand Down
5 changes: 5 additions & 0 deletions crates/core/src/alloc/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,11 @@ impl<T> Vec<T> {
// use `std`'s `into_boxed_slice` without fear of `realloc`.
Ok(self.inner.into_boxed_slice())
}

/// Same as [`std::vec::Vec::clear`].
pub fn clear(&mut self) {
self.inner.clear();
}
}

impl<T> Deref for Vec<T> {
Expand Down
Loading