wip
This commit is contained in:
parent
715fa51468
commit
f9f2de3dfb
@ -82,14 +82,12 @@ macro_rules! unborrow {
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! unsafe_impl_unborrow {
|
macro_rules! unsafe_impl_unborrow {
|
||||||
($type:ident) => {
|
($type:ident) => {
|
||||||
unsafe impl $crate::Unborrow for $type {
|
impl $crate::Unborrow for $type {
|
||||||
type Target = $type;
|
type Target = $type;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn unborrow<'a>(self) -> $crate::Unborrowed<'a, Self::Target>
|
unsafe fn unborrow_unchecked(&mut self) -> Self::Target {
|
||||||
where
|
$type { ..*self }
|
||||||
Self: 'a,
|
|
||||||
{
|
|
||||||
$crate::Unborrowed::new(self)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -43,75 +43,30 @@ impl<'a, T> DerefMut for Unborrowed<'a, T> {
|
|||||||
///
|
///
|
||||||
/// This allows writing HAL drivers that either own or borrow their peripherals, but that don't have
|
/// This allows writing HAL drivers that either own or borrow their peripherals, but that don't have
|
||||||
/// to store pointers in the borrowed case.
|
/// to store pointers in the borrowed case.
|
||||||
///
|
pub trait Unborrow: Sized {
|
||||||
/// Safety: this trait can be used to copy non-Copy types. Implementors must not cause
|
|
||||||
/// immediate UB when copied, and must not cause UB when copies are later used, provided they
|
|
||||||
/// are only used according the [`Self::unborrow`] safety contract.
|
|
||||||
///
|
|
||||||
pub unsafe trait Unborrow {
|
|
||||||
/// Unborrow result type
|
/// Unborrow result type
|
||||||
type Target;
|
type Target;
|
||||||
|
|
||||||
|
unsafe fn unborrow_unchecked(&mut self) -> Self::Target;
|
||||||
|
|
||||||
/// Unborrow a value.
|
/// Unborrow a value.
|
||||||
fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target>
|
#[inline]
|
||||||
where
|
fn unborrow<'a>(mut self) -> Unborrowed<'a, Self::Target>
|
||||||
Self: 'a;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl<'b, T: Unborrow> Unborrow for &'b mut T {
|
|
||||||
type Target = T::Target;
|
|
||||||
|
|
||||||
fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target>
|
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
{
|
{
|
||||||
// Safety: This returns a copy of a singleton that's normally not
|
Unborrowed::new(unsafe { self.unborrow_unchecked() })
|
||||||
// copiable. The returned copy must ONLY be used while the lifetime of `self` is
|
|
||||||
// valid, as if it were accessed through `self` every time.
|
|
||||||
T::unborrow(unsafe { core::ptr::read(self) })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<'b, T> Unborrow for Unborrowed<'b, T> {
|
impl<'b, T: DerefMut> Unborrow for T
|
||||||
type Target = T;
|
|
||||||
|
|
||||||
fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target>
|
|
||||||
where
|
where
|
||||||
Self: 'a,
|
T::Target: Unborrow,
|
||||||
{
|
{
|
||||||
self
|
type Target = <T::Target as Unborrow>::Target;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! unsafe_impl_unborrow_tuples {
|
#[inline]
|
||||||
($($t:ident),+) => {
|
unsafe fn unborrow_unchecked(&mut self) -> Self::Target {
|
||||||
unsafe impl<$($t),+> Unborrow for ($($t),+)
|
self.deref_mut().unborrow_unchecked()
|
||||||
where
|
|
||||||
$(
|
|
||||||
$t: Unborrow<Target = $t>
|
|
||||||
),+
|
|
||||||
{
|
|
||||||
type Target = ($($t),+);
|
|
||||||
fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target>
|
|
||||||
where
|
|
||||||
Self: 'a
|
|
||||||
{
|
|
||||||
Unborrowed::new(self)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe_impl_unborrow_tuples!(A, B);
|
|
||||||
unsafe_impl_unborrow_tuples!(A, B, C);
|
|
||||||
unsafe_impl_unborrow_tuples!(A, B, C, D);
|
|
||||||
unsafe_impl_unborrow_tuples!(A, B, C, D, E);
|
|
||||||
unsafe_impl_unborrow_tuples!(A, B, C, D, E, F);
|
|
||||||
unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G);
|
|
||||||
unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H);
|
|
||||||
unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I);
|
|
||||||
unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J);
|
|
||||||
unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J, K);
|
|
||||||
unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J, K, L);
|
|
||||||
|
Loading…
Reference in New Issue
Block a user