#[macro_export]
macro_rules! rental {
{
mod $rental_mod:ident {
$($items:tt)*
}
} => {
mod $rental_mod {
rental!{@ITEM $($items)*}
}
};
{
pub mod $rental_mod:ident {
$($items:tt)*
}
} => {
pub mod $rental_mod {
rental!{@ITEM $($items)*}
}
};
{
@ITEM use $($rest:tt)*
} => {
rental!(@USES use $($rest)*);
};
{
@USES $uses:item $($rest:tt)*
} => {
$uses
rental!(@ITEM $($rest)*);
};
{
@ITEM pub rental $rental:ident<'rental $(, $param:tt $(: [$($bounds:tt)*])*)*> (
$owner_ty:ty,
$($rental_ty:tt)*
) where [$($clause:tt)*];
$($rest:tt)*
} => {
#[deny(lifetime_underscore)]
pub struct $rental<'rental $(, $param $(: $($bounds)*)*)*> where
'static: 'rental,
$($clause)*
{
owner: ::std::option::Option<$owner_ty>,
rental: ::std::option::Option<$($rental_ty)*>,
}
impl<'rental $(, $param $(: $($bounds)*)*)*> $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
#[allow(dead_code)]
pub fn new<F__>(owner: $owner_ty, f: F__)
-> $rental<'rental $(, $param)*> where
F__: for<'a__> ::std::ops::FnOnce(&'a__ <$owner_ty as ::std::ops::Deref>::Target) -> rental_rebind__!('a__ $($rental_ty)*)
{
$crate::static_assert_fixed_deref__(&owner);
$rental{
rental: unsafe {
Some(::std::mem::transmute(f(&*<$owner_ty as ::std::ops::Deref>::deref(&owner))))
},
owner: Some(owner),
}
}
#[allow(dead_code)]
pub fn try_new<E__, F__>(owner: $owner_ty, f: F__)
-> ::std::result::Result<$rental<'rental $(, $param)*>, (E__, $owner_ty)> where
F__: for<'a__> ::std::ops::FnOnce(&'a__ <$owner_ty as ::std::ops::Deref>::Target) -> ::std::result::Result<rental_rebind__!('a__ $($rental_ty)*), E__>
{
$crate::static_assert_fixed_deref__(&owner);
Ok($rental{
rental: unsafe {
let ptr: *const _ = &*<$owner_ty as ::std::ops::Deref>::deref(&owner);
match f(&*ptr) {
Ok(asset) => Some(::std::mem::transmute(asset)),
Err(err) => return Err((err, owner)),
}
},
owner: Some(owner),
})
}
#[allow(dead_code)]
pub fn owner(&self) -> &$owner_ty {
self.owner.as_ref().unwrap()
}
#[allow(dead_code)]
pub fn rent<F__, R__>(&self, f: F__) -> R__ where
F__: for<'a__, 'r__> ::std::ops::FnOnce(&'a__ rental_rebind__!('r__ $($rental_ty)*)) -> R__,
{
f(self.rental.as_ref().unwrap())
}
#[allow(dead_code)]
pub fn rent_ref<F__, R__>(&self, f: F__) -> &R__ where
F__: for<'a__, 'r__> ::std::ops::FnOnce(&'a__ rental_rebind__!('r__ $($rental_ty)*)) -> &'a__ R__,
{
f(self.rental.as_ref().unwrap())
}
}
unsafe impl<'rental $(, $param $(: $($bounds)*)*)*> $crate::Rental for $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
type Owner = $owner_ty;
type Rental = $($rental_ty)*;
#[inline(always)]
unsafe fn rental(&self) -> &$($rental_ty)* { self.rental.as_ref().unwrap() }
fn from_parts(owner: $owner_ty, rent: $($rental_ty)*) -> Self { $rental{owner: Some(owner), rental: Some(rent)} }
unsafe fn into_parts(mut self) -> ($owner_ty, $($rental_ty)*) { (self.owner.take().unwrap(), self.rental.take().unwrap()) }
fn into_owner(mut self) -> $owner_ty { self.owner.take().unwrap() }
}
impl<'rental $(, $param $(: $($bounds)*)*)*> ::std::ops::Drop for $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
fn drop(&mut self) {
::std::mem::drop(self.rental.take());
::std::mem::drop(self.owner.take());
}
}
rental!{@ITEM $($rest)*}
};
{
@ITEM pub rental $rental:ident<'rental $(, $param:tt $(: [$($bounds:tt)*])*)*> (
$owner_ty:ty,
$($rental_ty:tt)*
): Deref($($deref_ty:tt)*) where [$($clause:tt)*];
$($rest:tt)*
} => {
#[deny(lifetime_underscore)]
pub struct $rental<'rental $(, $param $(: $($bounds)*)*)*> where
'static: 'rental,
$($clause)*
{
owner: ::std::option::Option<$owner_ty>,
rental: ::std::option::Option<$($rental_ty)*>,
}
impl<'rental $(, $param $(: $($bounds)*)*)*> $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
#[allow(dead_code)]
pub fn new<F__>(owner: $owner_ty, f: F__)
-> $rental<'rental $(, $param)*> where
F__: for<'a__> ::std::ops::FnOnce(&'a__ <$owner_ty as ::std::ops::Deref>::Target) -> rental_rebind__!('a__ $($rental_ty)*)
{
$crate::static_assert_fixed_deref__(&owner);
$rental{
rental: unsafe {
Some(::std::mem::transmute(f(&*<$owner_ty as ::std::ops::Deref>::deref(&owner))))
},
owner: Some(owner),
}
}
#[allow(dead_code)]
pub fn try_new<E__, F__>(owner: $owner_ty, f: F__)
-> ::std::result::Result<$rental<'rental $(, $param)*>, (E__, $owner_ty)> where
F__: for<'a__> ::std::ops::FnOnce(&'a__ <$owner_ty as ::std::ops::Deref>::Target) -> ::std::result::Result<rental_rebind__!('a__ $($rental_ty)*), E__>
{
$crate::static_assert_fixed_deref__(&owner);
Ok($rental{
rental: unsafe {
let ptr: *const _ = &*<$owner_ty as ::std::ops::Deref>::deref(&owner);
match f(&*ptr) {
Ok(asset) => Some(::std::mem::transmute(asset)),
Err(err) => return Err((err, owner)),
}
},
owner: Some(owner),
})
}
#[allow(dead_code)]
pub fn owner(&self) -> &$owner_ty {
self.owner.as_ref().unwrap()
}
#[allow(dead_code)]
pub fn rent<F__, R__>(&self, f: F__) -> R__ where
F__: for<'a__, 'r__> ::std::ops::FnOnce(&'a__ rental_rebind__!('r__ $($rental_ty)*)) -> R__,
{
f(self.rental.as_ref().unwrap())
}
#[allow(dead_code)]
pub fn rent_ref<F__, R__>(&self, f: F__) -> &R__ where
F__: for<'a__, 'r__> ::std::ops::FnOnce(&'a__ rental_rebind__!('r__ $($rental_ty)*)) -> &'a__ R__,
{
f(self.rental.as_ref().unwrap())
}
}
unsafe impl<'rental $(, $param $(: $($bounds)*)*)*> $crate::Rental for $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
type Owner = $owner_ty;
type Rental = $($rental_ty)*;
#[inline(always)]
unsafe fn rental(&self) -> &$($rental_ty)* { self.rental.as_ref().unwrap() }
fn from_parts(owner: $owner_ty, rent: $($rental_ty)*) -> Self { $rental{owner: Some(owner), rental: Some(rent)} }
unsafe fn into_parts(mut self) -> ($owner_ty, $($rental_ty)*) { (self.owner.take().unwrap(), self.rental.take().unwrap()) }
fn into_owner(mut self) -> $owner_ty { self.owner.take().unwrap() }
}
impl<'rental $(, $param $(: $($bounds)*)*)*> ::std::ops::Deref for $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
type Target = rental_deref_ty__!($($deref_ty)*);
#[inline(always)]
fn deref(&self) -> &rental_deref_ty__!($($deref_ty)*) {
use $crate::Rental;
unsafe { &**self.rental() }
}
}
impl<'rental $(, $param $(: $($bounds)*)*)*> ::std::convert::AsRef<rental_deref_ty__!($($deref_ty)*)> for $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
fn as_ref(&self) -> &rental_deref_ty__!($($deref_ty)*) { &**self }
}
impl<'rental $(, $param $(: $($bounds)*)*)*> ::std::borrow::Borrow<rental_deref_ty__!($($deref_ty)*)> for $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
fn borrow(&self) -> &rental_deref_ty__!($($deref_ty)*) { &**self }
}
impl<'rental $(, $param $(: $($bounds)*)*)*> ::std::ops::Drop for $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
fn drop(&mut self) {
::std::mem::drop(self.rental.take());
::std::mem::drop(self.owner.take());
}
}
rental!{@ITEM $($rest)*}
};
{
@ITEM pub rental mut $rental:ident<'rental $(, $param:tt $(: [$($bounds:tt)*])*)*> (
$owner_ty:ty,
$($rental_ty:tt)*
) where [$($clause:tt)*];
$($rest:tt)*
} => {
#[deny(lifetime_underscore)]
pub struct $rental<'rental $(, $param $(: $($bounds)*)*)*> where
'static: 'rental,
$($clause)*
{
owner: ::std::option::Option<$owner_ty>,
rental: ::std::option::Option<$($rental_ty)*>,
}
impl<'rental $(, $param $(: $($bounds)*)*)*> $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
#[allow(dead_code)]
pub fn new<F__>(mut owner: $owner_ty, f: F__)
-> $rental<'rental $(, $param)*> where
F__: for<'a__> ::std::ops::FnOnce(&'a__ mut <$owner_ty as ::std::ops::Deref>::Target) -> rental_rebind__!('a__ $($rental_ty)*)
{
$crate::static_assert_fixed_deref__(&owner);
$rental{
rental: unsafe {
Some(::std::mem::transmute(f(&mut *<$owner_ty as ::std::ops::DerefMut>::deref_mut(&mut owner))))
},
owner: Some(owner),
}
}
#[allow(dead_code)]
pub fn try_new<E__, F__>(mut owner: $owner_ty, f: F__)
-> ::std::result::Result<$rental<'rental $(, $param)*>, (E__, $owner_ty)> where
F__: for<'a__> ::std::ops::FnOnce(&'a__ mut <$owner_ty as ::std::ops::Deref>::Target) -> ::std::result::Result<rental_rebind__!('a__ $($rental_ty)*), E__>
{
$crate::static_assert_fixed_deref__(&owner);
Ok($rental{
rental: unsafe {
let ptr: *mut _ = &mut *<$owner_ty as ::std::ops::DerefMut>::deref_mut(&mut owner);
match f(&mut *ptr) {
Ok(asset) => Some(::std::mem::transmute(asset)),
Err(err) => return Err((err, owner)),
}
},
owner: Some(owner),
})
}
#[allow(dead_code)]
pub fn rent<F__, R__>(&self, f: F__) -> R__ where
F__: for<'a__, 'r__> ::std::ops::FnOnce(&'a__ rental_rebind__!('r__ $($rental_ty)*)) -> R__,
{
f(self.rental.as_ref().unwrap())
}
#[allow(dead_code)]
pub fn rent_mut<F__, R__>(&mut self, f: F__) -> R__ where
F__: for<'a__, 'r__> ::std::ops::FnOnce(&'a__ mut rental_rebind__!('r__ $($rental_ty)*)) -> R__,
{
f(self.rental.as_mut().unwrap())
}
#[allow(dead_code)]
pub fn rent_ref<F__, R__>(&self, f: F__) -> &R__ where
F__: for<'a__, 'r__> ::std::ops::FnOnce(&'a__ rental_rebind__!('r__ $($rental_ty)*)) -> &'a__ R__,
{
f(self.rental.as_ref().unwrap())
}
#[allow(dead_code)]
pub fn rent_mut_ref<F__, R__>(&mut self, f: F__) -> &mut R__ where
F__: for<'a__, 'r__> ::std::ops::FnOnce(&'a__ mut rental_rebind__!('r__ $($rental_ty)*)) -> &'a__ mut R__,
{
f(self.rental.as_mut().unwrap())
}
}
unsafe impl<'rental $(, $param $(: $($bounds)*)*)*> $crate::Rental for $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
type Owner = $owner_ty;
type Rental = $($rental_ty)*;
#[inline(always)]
unsafe fn rental(&self) -> &$($rental_ty)* { self.rental.as_ref().unwrap() }
fn from_parts(owner: $owner_ty, rent: $($rental_ty)*) -> Self { $rental{owner: Some(owner), rental: Some(rent)} }
unsafe fn into_parts(mut self) -> ($owner_ty, $($rental_ty)*) { (self.owner.take().unwrap(), self.rental.take().unwrap()) }
fn into_owner(mut self) -> $owner_ty { self.owner.take().unwrap() }
}
unsafe impl<'rental $(, $param $(: $($bounds)*)*)*> $crate::RentalMut for $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
#[inline(always)]
unsafe fn rental_mut(&mut self) -> &mut <Self as $crate::Rental>::Rental { self.rental.as_mut().unwrap() }
}
impl<'rental $(, $param $(: $($bounds)*)*)*> ::std::ops::Drop for $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
fn drop(&mut self) {
::std::mem::drop(self.rental.take());
::std::mem::drop(self.owner.take());
}
}
rental!{@ITEM $($rest)*}
};
{
@ITEM pub rental mut $rental:ident<'rental $(, $param:tt $(: [$($bounds:tt)*])*)*> (
$owner_ty:ty,
$($rental_ty:tt)*
): Deref($($deref_ty:tt)*) where [$($clause:tt)*];
$($rest:tt)*
} => {
#[deny(lifetime_underscore)]
pub struct $rental<'rental $(, $param $(: $($bounds)*)*)*> where
'static: 'rental,
$($clause)*
{
owner: ::std::option::Option<$owner_ty>,
rental: ::std::option::Option<$($rental_ty)*>,
}
impl<'rental $(, $param $(: $($bounds)*)*)*> $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
#[allow(dead_code)]
pub fn new<F__>(mut owner: $owner_ty, f: F__)
-> $rental<'rental $(, $param)*> where
F__: for<'a__> ::std::ops::FnOnce(&'a__ mut <$owner_ty as ::std::ops::Deref>::Target) -> rental_rebind__!('a__ $($rental_ty)*)
{
$crate::static_assert_fixed_deref__(&owner);
$rental{
rental: unsafe {
Some(::std::mem::transmute(f(&mut *<$owner_ty as ::std::ops::DerefMut>::deref_mut(&mut owner))))
},
owner: Some(owner),
}
}
#[allow(dead_code)]
pub fn try_new<E__, F__>(mut owner: $owner_ty, f: F__)
-> ::std::result::Result<$rental<'rental $(, $param)*>, (E__, $owner_ty)> where
F__: for<'a__> ::std::ops::FnOnce(&'a__ mut <$owner_ty as ::std::ops::Deref>::Target) -> ::std::result::Result<rental_rebind__!('a__ $($rental_ty)*), E__>
{
$crate::static_assert_fixed_deref__(&owner);
Ok($rental{
rental: unsafe {
let ptr: *mut _ = &mut *<$owner_ty as ::std::ops::DerefMut>::deref_mut(&mut owner);
match f(&mut *ptr) {
Ok(asset) => Some(::std::mem::transmute(asset)),
Err(err) => return Err((err, owner)),
}
},
owner: Some(owner),
})
}
#[allow(dead_code)]
pub fn rent<F__, R__>(&self, f: F__) -> R__ where
F__: for<'a__, 'r__> ::std::ops::FnOnce(&'a__ rental_rebind__!('r__ $($rental_ty)*)) -> R__,
{
f(self.rental.as_ref().unwrap())
}
#[allow(dead_code)]
pub fn rent_mut<F__, R__>(&mut self, f: F__) -> R__ where
F__: for<'a__, 'r__> ::std::ops::FnOnce(&'a__ mut rental_rebind__!('r__ $($rental_ty)*)) -> R__,
{
f(self.rental.as_mut().unwrap())
}
#[allow(dead_code)]
pub fn rent_ref<F__, R__>(&self, f: F__) -> &R__ where
F__: for<'a__, 'r__> ::std::ops::FnOnce(&'a__ rental_rebind__!('r__ $($rental_ty)*)) -> &'a__ R__,
{
f(self.rental.as_ref().unwrap())
}
#[allow(dead_code)]
pub fn rent_mut_ref<F__, R__>(&mut self, f: F__) -> &mut R__ where
F__: for<'a__, 'r__> ::std::ops::FnOnce(&'a__ mut rental_rebind__!('r__ $($rental_ty)*)) -> &'a__ mut R__,
{
f(self.rental.as_mut().unwrap())
}
}
unsafe impl<'rental $(, $param $(: $($bounds)*)*)*> $crate::Rental for $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
type Owner = $owner_ty;
type Rental = $($rental_ty)*;
#[inline(always)]
unsafe fn rental(&self) -> &$($rental_ty)* { self.rental.as_ref().unwrap() }
fn from_parts(owner: $owner_ty, rent: $($rental_ty)*) -> Self { $rental{owner: Some(owner), rental: Some(rent)} }
unsafe fn into_parts(mut self) -> ($owner_ty, $($rental_ty)*) { (self.owner.take().unwrap(), self.rental.take().unwrap()) }
fn into_owner(mut self) -> $owner_ty { self.owner.take().unwrap() }
}
unsafe impl<'rental $(, $param $(: $($bounds)*)*)*> $crate::RentalMut for $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
#[inline(always)]
unsafe fn rental_mut(&mut self) -> &mut <Self as $crate::Rental>::Rental { self.rental.as_mut().unwrap() }
}
impl<'rental $(, $param $(: $($bounds)*)*)*> ::std::ops::Deref for $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
type Target = rental_deref_ty__!($($deref_ty)*);
#[inline(always)]
fn deref(&self) -> &rental_deref_ty__!($($deref_ty)*) {
use $crate::Rental;
unsafe { &**self.rental() }
}
}
impl<'rental $(, $param $(: $($bounds)*)*)*> ::std::ops::DerefMut for $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
#[inline(always)]
fn deref_mut(&mut self) -> &mut <<$rental<'rental $(, $param)*> as $crate::Rental>::Rental as ::std::ops::Deref>::Target {
use $crate::RentalMut;
unsafe { <<$rental<'rental $(, $param)*> as $crate::Rental>::Rental as ::std::ops::DerefMut>::deref_mut(self.rental_mut()) }
}
}
impl<'rental $(, $param $(: $($bounds)*)*)*> ::std::convert::AsRef<rental_deref_ty__!($($deref_ty)*)> for $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
fn as_ref(&self) -> &rental_deref_ty__!($($deref_ty)*) { &**self }
}
impl<'rental $(, $param $(: $($bounds)*)*)*> ::std::convert::AsMut<rental_deref_ty__!($($deref_ty)*)> for $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
fn as_mut(&mut self) -> &mut rental_deref_ty__!($($deref_ty)*) { &mut **self }
}
impl<'rental $(, $param $(: $($bounds)*)*)*> ::std::borrow::Borrow<rental_deref_ty__!($($deref_ty)*)> for $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
fn borrow(&self) -> &rental_deref_ty__!($($deref_ty)*) { &**self }
}
impl<'rental $(, $param $(: $($bounds)*)*)*> ::std::borrow::BorrowMut<rental_deref_ty__!($($deref_ty)*)> for $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
fn borrow_mut(&mut self) -> &mut rental_deref_ty__!($($deref_ty)*) { &mut **self }
}
impl<'rental $(, $param $(: $($bounds)*)*)*> ::std::ops::Drop for $rental<'rental $(, $param)*> where
'static: 'rental,
$($clause)*
{
fn drop(&mut self) {
::std::mem::drop(self.rental.take());
::std::mem::drop(self.owner.take());
}
}
rental!{@ITEM $($rest)*}
};
{
@ITEM pub mapper $mapper:ident<'rental $(, $param:tt $(: [$($bounds:tt)*])*)*>($($from_ty:tt)*) -> ($($into_ty:tt)*) where [$($clause:tt)*];
$($rest:tt)*
} => {
#[allow(dead_code)]
pub struct $mapper;
impl $mapper {
#[allow(dead_code)]
pub fn map<'rental $(, $param $(: $($bounds)*)*)*, T__, U__, F__>(t: T__, f: F__) -> U__ where
T__: $crate::Rental<Rental=$($from_ty)*>,
U__: $crate::Rental<Owner=<T__ as $crate::Rental>::Owner, Rental=$($into_ty)*>,
F__: for<'f__: 'rental> ::std::ops::FnOnce(rental_rebind__!('f__ $($from_ty)*)) -> rental_rebind__!('f__ $($into_ty)*),
$($clause)*
{
unsafe {
let (o, r) = t.into_parts();
U__::from_parts(o, f(r))
}
}
#[allow(dead_code)]
pub fn try_map<'rental $(, $param $(: $($bounds)*)*)*, T__, U__, E__, F__>(t: T__, f: F__) -> ::std::result::Result<U__, (E__, T__)> where
T__: $crate::Rental<Rental=$($from_ty)*>,
U__: $crate::Rental<Owner=<T__ as $crate::Rental>::Owner, Rental=$($into_ty)*>,
F__: for<'f__: 'rental> ::std::ops::FnOnce(rental_rebind__!('f__ $($from_ty)*)) -> ::std::result::Result<rental_rebind__!('f__ $($into_ty)*), (E__, rental_rebind__!('f__ $($from_ty)*))>,
$($clause)*
{
unsafe {
let (o, r) = t.into_parts();
match f(r) {
Ok(r) => Ok(U__::from_parts(o, r)),
Err((e, r)) => Err((e, T__::from_parts(o, r))),
}
}
}
}
rental!{@ITEM $($rest)*}
};
{
@ITEM pub rental mut $rental:ident<'rental $(, $param:tt $(: [$($bounds:tt)*])*)*>($($body:tt)*)$(: Deref($($target_ty:tt)*))*; $($rest:tt)*
} => {
rental!{@ITEM pub rental mut $rental<'rental $(, $param $(: [$($bounds)*])*)*>($($body)*)$(: Deref($($target_ty)*))* where []; $($rest)*}
};
{
@ITEM pub rental $rental:ident<'rental $(, $param:tt $(: [$($bounds:tt)*])*)*>($($body:tt)*)$(: Deref($($target_ty:tt)*))*; $($rest:tt)*
} => {
rental!{@ITEM pub rental $rental<'rental $(, $param $(: [$($bounds)*])*)*>($($body)*)$(: Deref($($target_ty)*))* where []; $($rest)*}
};
{
@ITEM pub mapper $mapper:ident<'rental $(, $param:tt $(: [$($bounds:tt)*])*)*> ($($from_ty:tt)*) -> ($($into_ty:tt)*); $($rest:tt)*
} => {
rental!{@ITEM pub mapper $mapper<'rental $(, $param $(: [$($bounds)*])*)*> ($($from_ty)*) -> ($($into_ty)*) where []; $($rest)*}
};
{ @ITEM } => { };
}
#[doc(hidden)]
#[macro_export]
macro_rules! rental_rebind__ {
(
$into:tt {$($head:tt)*} 'rental $($tail:tt)*
) => {
rental_rebind__!($into {$($head)* $into} $($tail)*)
};
(
$into:tt {$($head:tt)*} ($($inner:tt)*) $($tail:tt)*
) => {
rental_rebind__!($into {($($head)*)} $($inner)* @> $($tail)*)
};
(
$into:tt {$($head:tt)*} [$($inner:tt)*] $($tail:tt)*
) => {
rental_rebind__!($into {[$($head)*]} $($inner)* @> $($tail)*)
};
(
$into:tt {$($head:tt)*} {$($inner:tt)*} $($tail:tt)*
) => {
rental_rebind__!($into {{$($head)*}} $($inner)* @> $($tail)*)
};
(
$into:tt {($($head:tt)*) $($inner:tt)*} @> $($tail:tt)*
) => {
rental_rebind__!($into {$($head)*($($inner)*)} $($tail)*)
};
(
$into:tt {[$($head:tt)*] $($inner:tt)*} @> $($tail:tt)*
) => {
rental_rebind__!($into {$($head)*[$($inner)*]} $($tail)*)
};
(
$into:tt {{$($head:tt)*} $($inner:tt)*} @> $($tail:tt)*
) => {
rental_rebind__!($into {$($head)*{$($inner)*}} $($tail)*)
};
(
$into:tt {$($head:tt)*} $tok:tt $($tail:tt)*
) => {
rental_rebind__!($into {$($head)* $tok} $($tail)*)
};
(
$into:tt {$($rebound:tt)*}
) => {
$($rebound)*
};
(
$into:tt $($tail:tt)*
) => {
rental_rebind__!($into {} $($tail)*)
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! rental_deref_ty__ {
( ) => { $crate::NoDeref };
( $($deref_ty:tt)+ ) => { rental_rebind__!('_ $($deref_ty)+) };
}
use std::ops::Deref;
use std::{cell, rc, sync};
#[doc(hidden)]
#[allow(dead_code)]
#[inline(always)]
pub fn static_assert_fixed_deref__<O: FixedDeref>(_: &O) { }
pub unsafe trait FixedDeref: Deref { }
unsafe impl<'t, T: ?Sized> FixedDeref for &'t T { }
unsafe impl<'t, T: ?Sized> FixedDeref for &'t mut T { }
unsafe impl<T: ?Sized> FixedDeref for Box<T> { }
unsafe impl<T> FixedDeref for Vec<T> { }
unsafe impl FixedDeref for String { }
unsafe impl<T: ?Sized> FixedDeref for rc::Rc<T> { }
unsafe impl<T: ?Sized> FixedDeref for sync::Arc<T> { }
unsafe impl<'t, T: ?Sized> FixedDeref for cell::Ref<'t, T> { }
unsafe impl<'t, T: ?Sized> FixedDeref for cell::RefMut<'t, T> { }
unsafe impl<'t, T: ?Sized> FixedDeref for sync::MutexGuard<'t, T> { }
unsafe impl<'t, T: ?Sized> FixedDeref for sync::RwLockReadGuard<'t, T> { }
unsafe impl<'t, T: ?Sized> FixedDeref for sync::RwLockWriteGuard<'t, T> { }
pub unsafe trait Rental {
type Owner: FixedDeref;
type Rental;
unsafe fn rental(&self) -> &<Self as Rental>::Rental;
fn from_parts(<Self as Rental>::Owner, <Self as Rental>::Rental) -> Self;
unsafe fn into_parts(self) -> (<Self as Rental>::Owner, <Self as Rental>::Rental);
fn into_owner(self) -> <Self as Rental>::Owner;
}
pub unsafe trait RentalMut: Rental {
unsafe fn rental_mut(&mut self) -> &mut <Self as Rental>::Rental;
}
#[doc(hidden)]
pub enum NoDeref { }
rental! {
mod premade {
use super::FixedDeref;
use std::ops::DerefMut;
pub rental RentRef<'rental, T: [FixedDeref + 'rental], B: [?Sized + 'rental]> (T, &'rental B): Deref(B);
pub rental mut RentMut<'rental, T: [FixedDeref + DerefMut + 'rental], B: [?Sized + 'rental]>(T, &'rental mut B): Deref(B);
pub mapper MapRef<'rental, T: ['rental], U: [?Sized + 'rental]>(&'rental T) -> (&'rental U);
pub mapper MapMut<'rental, T: ['rental], U: [?Sized + 'rental]>(&'rental mut T) -> (&'rental mut U);
}
}
pub use premade::*;
pub type RentArc<'rental, T: 'rental, B: 'rental> = RentRef<'rental, sync::Arc<T>, B>;
pub type RentBox<'rental, T: 'rental, B: 'rental> = RentRef<'rental, Box<T>, B>;
pub type RentBoxMut<'rental, T: 'rental, B: 'rental> = RentMut<'rental, Box<T>, B>;
pub type RentMutex<'rental, T: 'rental, B: 'rental> = RentRef<'rental, sync::MutexGuard<'rental, T>, B>;
pub type RentMutexMut<'rental, T: 'rental, B: 'rental> = RentMut<'rental, sync::MutexGuard<'rental, T>, B>;
pub type RentRefCell<'rental, T: 'rental, B: 'rental> = RentRef<'rental, cell::Ref<'rental, T>, B>;
pub type RentRefCellMut<'rental, T: 'rental, B: 'rental> = RentMut<'rental, cell::RefMut<'rental, T>, B>;
pub type RentRwLock<'rental, T: 'rental, B: 'rental> = RentRef<'rental, sync::RwLockReadGuard<'rental, T>, B>;
pub type RentRwLockMut<'rental, T: 'rental, B: 'rental> = RentMut<'rental, sync::RwLockWriteGuard<'rental, T>, B>;
pub type RentString<'rental, B: 'rental> = RentRef<'rental, String, B>;
pub type RentStringMut<'rental, B: 'rental> = RentMut<'rental, String, B>;
pub type RentVec<'rental, T: 'rental, B: 'rental> = RentRef<'rental, Vec<T>, B>;
pub type RentVecMut<'rental, T: 'rental, B: 'rental> = RentMut<'rental, Vec<T>, B>;
#[cfg(test)]
mod test {
use std::ops::{Deref, DerefMut};
use std::fmt::{self, Debug, Display};
pub struct Foo<T> {
val: T,
}
pub struct FooBorrow<'f, T: 'f> {
val: &'f T,
}
pub struct FooBorrowMut<'f, T: 'f> {
val: &'f mut T,
}
impl<T> Foo<T> {
pub fn borrow(&self) -> FooBorrow<T> { FooBorrow{val: &self.val} }
pub fn borrow_mut(&mut self) -> FooBorrowMut<T> { FooBorrowMut{val: &mut self.val} }
}
impl<'f, T> FooBorrow<'f, T> {
pub fn frob(self) -> FooBorrow<'f, T> { self }
pub fn try_frob(self) -> Result<FooBorrow<'f, T>, (String, FooBorrow<'f, T>)> { Ok(self) }
}
impl<'f, T> Deref for FooBorrow<'f, T> {
type Target = T;
fn deref(&self) -> &T { self.val }
}
impl<'f, T> Clone for FooBorrow<'f, T> {
fn clone(&self) -> FooBorrow<'f, T> {
FooBorrow{val: self.val}
}
}
impl<'f, T: Debug> Debug for FooBorrow<'f, T> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&**self, fmt)
}
}
impl<'f, T: Display> Display for FooBorrow<'f, T> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&**self, fmt)
}
}
impl<'f, T> FooBorrowMut<'f, T> {
pub fn frob(self) -> FooBorrowMut<'f, T> { self }
pub fn fail_frob(self) -> Result<FooBorrowMut<'f, T>, (String, FooBorrowMut<'f, T>)> { Err(("Error".to_string(), self)) }
}
impl<'f, T> Deref for FooBorrowMut<'f, T> {
type Target = T;
fn deref(&self) -> &T { self.val }
}
impl<'f, T> DerefMut for FooBorrowMut<'f, T> {
fn deref_mut(&mut self) -> &mut T { self.val }
}
impl<'f, T: Debug> Debug for FooBorrowMut<'f, T> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&**self, fmt)
}
}
impl<'f, T: Display> Display for FooBorrowMut<'f, T> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&**self, fmt)
}
}
rental!{
mod test {
use super::*;
pub rental RentFoo<'rental, T: ['rental]> (Box<Foo<T>>, FooBorrow<'rental, T>): Deref(T);
pub rental mut RentFooMut<'rental, T: ['rental]> (Box<Foo<T>>, FooBorrowMut<'rental, T>): Deref(T);
pub mapper MapFoo<'rental, T> (FooBorrow<'rental, T>) -> (FooBorrow<'rental, T>) where [T: 'rental];
pub mapper MapFooMut<'rental, T> (FooBorrowMut<'rental, T>) -> (FooBorrowMut<'rental, T>) where [T: 'rental];
pub rental TestFooI32<'rental> (Box<Foo<i32>>, FooBorrow<'rental, i32>): Deref(i32);
pub rental TestFooMutI32<'rental> (Box<Foo<i32>>, FooBorrowMut<'rental, i32>): Deref(i32);
pub rental TestFooBox<'rental, T: ['rental]> (Box<Foo<T>>, Box<FooBorrow<'rental, T>>);
pub rental mut TestFooMutBox<'rental, T: ['rental]> (Box<Foo<T>>, Box<FooBorrowMut<'rental, T>>);
}
}
use self::test::*;
#[test]
fn new() {
RentFoo::new(Box::new(Foo{val: 5}), |f| f.borrow());
}
#[test]
fn new_mut() {
RentFooMut::new(Box::new(Foo{val: 5}), |f| f.borrow_mut());
}
#[test]
fn rent() {
let foo = RentFoo::new(Box::new(Foo{val: 5}), |f| f.borrow());
assert_eq!(foo.rent(|fb| **fb), 5);
}
#[test]
fn rent_mut() {
let mut foo = RentFooMut::new(Box::new(Foo{val: 5}), |f| f.borrow_mut());
foo.rent_mut(|fbm| (*fbm.val) = 12);
assert_eq!(foo.rent(|fbm| **fbm), 12);
}
#[test]
fn rent_ref() {
let foo = RentFoo::new(Box::new(Foo{val: 5}), |f| f.borrow());
let ft = foo.rent_ref(|fb| fb.val);
assert_eq!(*ft, 5);
}
#[test]
fn rent_mut_ref() {
let mut foo = RentFooMut::new(Box::new(Foo{val: 5}), |f| f.borrow_mut());
let ft = foo.rent_mut_ref(|fbm| fbm.val);
*ft = 3;
assert_eq!(*ft, 3);
}
#[test]
fn deref() {
let foo = RentFoo::new(Box::new(Foo{val: 5}), |f| f.borrow());
assert_eq!(*foo, 5);
}
#[test]
fn deref_mut() {
let mut foo_mut = RentFooMut::new(Box::new(Foo{val: 5}), |f| f.borrow_mut());
*foo_mut = 12;
assert_eq!(*foo_mut, 12);
}
#[test]
fn map() {
let mut foo = RentFoo::new(Box::new(Foo{val: 5}), |f| f.borrow());
foo = MapFoo::map(foo, |b| b.frob());
foo.rent(|b| assert_eq!(**b, 5));
let mut foo_mut = RentFooMut::new(Box::new(Foo{val: 12}), |f| f.borrow_mut());
foo_mut = MapFooMut::map(foo_mut, |b| b.frob());
foo_mut.rent_mut(|b| assert_eq!(**b, 12));
}
#[test]
fn try_map() {
let mut foo = RentFoo::new(Box::new(Foo{val: 5}), |f| f.borrow());
foo = match MapFoo::try_map(foo, |b| b.try_frob()) {
Ok(f) => f,
Err((_, _)) => panic!(),
};
foo.rent(|b| assert_eq!(**b, 5));
let mut _foo_mut = RentFooMut::new(Box::new(Foo{val: 12}), |f| f.borrow_mut());
_foo_mut = match MapFooMut::try_map(_foo_mut, |b| b.fail_frob()) {
Ok(f) => f,
Err((e, mut f)) => {
assert_eq!(e, "Error");
f.rent_mut(|b| assert_eq!(**b, 12));
return;
},
};
panic!();
}
#[test]
fn borrow() {
let foo = RentFoo::new(Box::new(Foo{val: 5}), |f| f.borrow());
let _: &i32 = ::std::convert::AsRef::as_ref(&foo);
let _: &i32 = ::std::borrow::Borrow::borrow(&foo);
let mut foo_mut = RentFooMut::new(Box::new(Foo{val: 5}), |f| f.borrow_mut());
let _: &mut i32 = ::std::convert::AsMut::as_mut(&mut foo_mut);
let _: &mut i32 = ::std::borrow::BorrowMut::borrow_mut(&mut foo_mut);
}
}