mod accum;
mod collect;
mod double_ended;
mod exact_size;
mod ext;
mod fallible_lender;
mod lender;
mod marker;
pub use self::{
accum::{ProductFallibleLender, ProductLender, SumFallibleLender, SumLender},
collect::{
ExtendFallibleLender, ExtendLender, FromFallibleLender, FromLender, IntoFallibleLender,
IntoLender,
},
double_ended::{DoubleEndedFallibleLender, DoubleEndedLender},
exact_size::{ExactSizeFallibleLender, ExactSizeLender},
ext::{
FallibleIteratorExt, FallibleIteratorRefExt, IntoFallibleIteratorExt, IntoIteratorExt,
IteratorExt, IteratorRefExt,
},
fallible_lender::{FallibleLend, FallibleLender, FallibleLending},
lender::{Lend, Lender, Lending},
marker::{FusedFallibleLender, FusedLender},
};
pub trait TupleLend<'a> {
type First: 'a;
type Second: 'a;
fn tuple_lend(self) -> (Self::First, Self::Second);
}
impl<'a, A: 'a, B: 'a> TupleLend<'a> for (A, B) {
type First = A;
type Second = B;
#[inline(always)]
fn tuple_lend(self) -> (Self::First, Self::Second) {
(self.0, self.1)
}
}
impl<'a, A, B> TupleLend<'a> for &'a (A, B) {
type First = &'a A;
type Second = &'a B;
#[inline(always)]
fn tuple_lend(self) -> (Self::First, Self::Second) {
(&self.0, &self.1)
}
}
impl<'a, A, B> TupleLend<'a> for &'a mut (A, B) {
type First = &'a mut A;
type Second = &'a mut B;
#[inline(always)]
fn tuple_lend(self) -> (Self::First, Self::Second) {
(&mut self.0, &mut self.1)
}
}
#[doc(hidden)]
pub struct CovariantProof<T>(core::marker::PhantomData<fn() -> T>);
impl<T> CovariantProof<T> {
#[doc(hidden)]
pub(crate) fn new() -> Self {
CovariantProof(core::marker::PhantomData)
}
}
#[doc(hidden)]
pub struct DynLendShunt<T: ?Sized>(pub T);
impl<'lend, T: ?Sized + for<'all> DynLend<'all>> Lending<'lend> for DynLendShunt<T> {
type Lend = <T as DynLend<'lend>>::Lend;
}
#[doc(hidden)]
pub trait CovariantLending: for<'all> Lending<'all> {
fn __check_covariance<'long: 'short, 'short>(
proof: CovariantProof<<Self as Lending<'long>>::Lend>,
) -> CovariantProof<<Self as Lending<'short>>::Lend>;
}
impl<T: ?Sized + for<'all> DynLend<'all>> CovariantLending for DynLendShunt<T> {
fn __check_covariance<'long: 'short, 'short>(
proof: CovariantProof<<Self as Lending<'long>>::Lend>,
) -> CovariantProof<<Self as Lending<'short>>::Lend> {
unsafe { core::mem::transmute(proof) }
}
}
#[doc(hidden)]
pub trait DynLend<'lend> {
type Lend;
}
#[doc(hidden)]
#[macro_export]
macro_rules! __lend_impl {
($Shunt:ident, $Trait:ident, $T:ident) => {
$crate::$Shunt<dyn for<'lend> $crate::$Trait<'lend, Lend = $T>>
};
($Shunt:ident, $Trait:ident, &$lt:lifetime $T:ident) => {
$crate::$Shunt<dyn for<'lend> $crate::$Trait<'lend, Lend = &$lt $T>>
};
($Shunt:ident, $Trait:ident, &$lt:lifetime mut $T:ident) => {
$crate::$Shunt<dyn for<'lend> $crate::$Trait<'lend, Lend = &$lt mut $T>>
};
($Shunt:ident, $Trait:ident, &$lt:lifetime str) => {
$crate::$Shunt<dyn for<'lend> $crate::$Trait<'lend, Lend = &$lt str>>
};
($Shunt:ident, $Trait:ident, &$lt:lifetime mut str) => {
$crate::$Shunt<dyn for<'lend> $crate::$Trait<'lend, Lend = &$lt mut str>>
};
($Shunt:ident, $Trait:ident, &$lt:lifetime [$T:ident]) => {
$crate::$Shunt<dyn for<'lend> $crate::$Trait<'lend, Lend = &$lt [$T]>>
};
($Shunt:ident, $Trait:ident, &$lt:lifetime mut [$T:ident]) => {
$crate::$Shunt<dyn for<'lend> $crate::$Trait<'lend, Lend = &$lt mut [$T]>>
};
($Shunt:ident, $Trait:ident, Vec<$T:ident>) => {
$crate::$Shunt<dyn for<'lend> $crate::$Trait<'lend, Lend = Vec<$T>>>
};
($Shunt:ident, $Trait:ident, &$lt:lifetime Vec<$T:ident>) => {
$crate::$Shunt<dyn for<'lend> $crate::$Trait<'lend, Lend = &$lt Vec<$T>>>
};
($Shunt:ident, $Trait:ident, &$lt:lifetime mut Vec<$T:ident>) => {
$crate::$Shunt<dyn for<'lend> $crate::$Trait<'lend, Lend = &$lt mut Vec<$T>>>
};
($Shunt:ident, $Trait:ident, & &$lt:lifetime $T:ident) => {
$crate::$Shunt<dyn for<'lend> $crate::$Trait<'lend, Lend = & &$lt $T>>
};
($Shunt:ident, $Trait:ident, &&$lt:lifetime $T:ident) => {
$crate::$Shunt<dyn for<'lend> $crate::$Trait<'lend, Lend = &&$lt $T>>
};
($Shunt:ident, $Trait:ident, & &$lt:lifetime mut $T:ident) => {
$crate::$Shunt<dyn for<'lend> $crate::$Trait<'lend, Lend = & &$lt mut $T>>
};
($Shunt:ident, $Trait:ident, &&$lt:lifetime mut $T:ident) => {
$crate::$Shunt<dyn for<'lend> $crate::$Trait<'lend, Lend = &&$lt mut $T>>
};
($Shunt:ident, $Trait:ident, &$lt:lifetime ($($T:ident),+)) => {
$crate::$Shunt<dyn for<'lend> $crate::$Trait<'lend, Lend = &$lt ($($T),+)>>
};
($Shunt:ident, $Trait:ident, &$lt:lifetime mut ($($T:ident),+)) => {
$crate::$Shunt<dyn for<'lend> $crate::$Trait<'lend, Lend = &$lt mut ($($T),+)>>
};
($Shunt:ident, $Trait:ident, ($($T:ident),+)) => {
$crate::$Shunt<dyn for<'lend> $crate::$Trait<'lend, Lend = ($($T),+)>>
};
}
#[macro_export]
macro_rules! lend {
($T:ident) => { $crate::__lend_impl!(DynLendShunt, DynLend, $T) };
(&$lt:lifetime $T:ident) => { $crate::__lend_impl!(DynLendShunt, DynLend, &$lt $T) };
(&$lt:lifetime mut $T:ident) => { $crate::__lend_impl!(DynLendShunt, DynLend, &$lt mut $T) };
(&$lt:lifetime str) => { $crate::__lend_impl!(DynLendShunt, DynLend, &$lt str) };
(&$lt:lifetime mut str) => { $crate::__lend_impl!(DynLendShunt, DynLend, &$lt mut str) };
(&$lt:lifetime [$T:ident]) => { $crate::__lend_impl!(DynLendShunt, DynLend, &$lt [$T]) };
(&$lt:lifetime mut [$T:ident]) => { $crate::__lend_impl!(DynLendShunt, DynLend, &$lt mut [$T]) };
(Vec<$T:ident>) => { $crate::__lend_impl!(DynLendShunt, DynLend, Vec<$T>) };
(&$lt:lifetime Vec<$T:ident>) => { $crate::__lend_impl!(DynLendShunt, DynLend, &$lt Vec<$T>) };
(&$lt:lifetime mut Vec<$T:ident>) => { $crate::__lend_impl!(DynLendShunt, DynLend, &$lt mut Vec<$T>) };
(& &$lt:lifetime $T:ident) => { $crate::__lend_impl!(DynLendShunt, DynLend, & &$lt $T) };
(&&$lt:lifetime $T:ident) => { $crate::__lend_impl!(DynLendShunt, DynLend, &&$lt $T) };
(& &$lt:lifetime mut $T:ident) => { $crate::__lend_impl!(DynLendShunt, DynLend, & &$lt mut $T) };
(&&$lt:lifetime mut $T:ident) => { $crate::__lend_impl!(DynLendShunt, DynLend, &&$lt mut $T) };
(&$lt:lifetime ($($T:ident),+ $(,)?)) => { $crate::__lend_impl!(DynLendShunt, DynLend, &$lt ($($T),+)) };
(&$lt:lifetime mut ($($T:ident),+ $(,)?)) => { $crate::__lend_impl!(DynLendShunt, DynLend, &$lt mut ($($T),+)) };
(($($T:ident),+ $(,)?)) => { $crate::__lend_impl!(DynLendShunt, DynLend, ($($T),+)) };
($($tt:tt)*) => {
compile_error!(concat!(
"lend!() only accepts simple covariant patterns. ",
"For complex types, use covariant_lend!(Name = YourType) instead."
))
};
}
#[macro_export]
macro_rules! check_covariance {
() => {
fn __check_covariance<'long: 'short, 'short>(
proof: $crate::CovariantProof<<Self as $crate::Lending<'long>>::Lend>,
) -> $crate::CovariantProof<<Self as $crate::Lending<'short>>::Lend> {
proof
}
};
}
#[macro_export]
macro_rules! unsafe_assume_covariance {
() => {
fn __check_covariance<'long: 'short, 'short>(
proof: $crate::CovariantProof<<Self as $crate::Lending<'long>>::Lend>,
) -> $crate::CovariantProof<<Self as $crate::Lending<'short>>::Lend> {
unsafe { core::mem::transmute(proof) }
}
};
}
#[macro_export]
macro_rules! covariant_lend {
($vis:vis $name:ident = $T:ty) => {
#[derive(Clone, Copy, Debug, Default)]
$vis struct $name;
impl<'lend> $crate::Lending<'lend> for $name {
type Lend = $T;
}
impl $crate::CovariantLending for $name {
fn __check_covariance<'long: 'short, 'short>(
proof: $crate::CovariantProof<<Self as $crate::Lending<'long>>::Lend>,
) -> $crate::CovariantProof<<Self as $crate::Lending<'short>>::Lend> {
proof
}
}
};
}
#[macro_export]
macro_rules! covariant_fallible_lend {
($vis:vis $name:ident = $T:ty) => {
#[derive(Clone, Copy, Debug, Default)]
$vis struct $name;
impl<'lend> $crate::FallibleLending<'lend> for $name {
type Lend = $T;
}
impl $crate::CovariantFallibleLending for $name {
fn __check_covariance<'long: 'short, 'short>(
proof: $crate::CovariantProof<&'short <Self as $crate::FallibleLending<'long>>::Lend>,
) -> $crate::CovariantProof<&'short <Self as $crate::FallibleLending<'short>>::Lend> {
proof
}
}
};
}
#[macro_export]
macro_rules! check_covariance_fallible {
() => {
fn __check_covariance<'long: 'short, 'short>(
proof: $crate::CovariantProof<&'short <Self as $crate::FallibleLending<'long>>::Lend>,
) -> $crate::CovariantProof<&'short <Self as $crate::FallibleLending<'short>>::Lend> {
proof
}
};
}
#[macro_export]
macro_rules! unsafe_assume_covariance_fallible {
() => {
fn __check_covariance<'long: 'short, 'short>(
proof: $crate::CovariantProof<&'short <Self as $crate::FallibleLending<'long>>::Lend>,
) -> $crate::CovariantProof<&'short <Self as $crate::FallibleLending<'short>>::Lend> {
unsafe { core::mem::transmute(proof) }
}
};
}
#[doc(hidden)]
pub struct DynFallibleLendShunt<T: ?Sized>(pub T);
impl<'lend, T: ?Sized + for<'all> DynFallibleLend<'all>> FallibleLending<'lend>
for DynFallibleLendShunt<T>
{
type Lend = <T as DynFallibleLend<'lend>>::Lend;
}
#[doc(hidden)]
pub trait CovariantFallibleLending: for<'all> FallibleLending<'all> {
fn __check_covariance<'long: 'short, 'short>(
proof: CovariantProof<&'short <Self as FallibleLending<'long>>::Lend>,
) -> CovariantProof<&'short <Self as FallibleLending<'short>>::Lend>;
}
impl<T: ?Sized + for<'all> DynFallibleLend<'all>> CovariantFallibleLending
for DynFallibleLendShunt<T>
{
fn __check_covariance<'long: 'short, 'short>(
proof: CovariantProof<&'short <Self as FallibleLending<'long>>::Lend>,
) -> CovariantProof<&'short <Self as FallibleLending<'short>>::Lend> {
unsafe { core::mem::transmute(proof) }
}
}
#[doc(hidden)]
pub trait DynFallibleLend<'lend> {
type Lend;
}
#[macro_export]
macro_rules! fallible_lend {
($T:ident) => { $crate::__lend_impl!(DynFallibleLendShunt, DynFallibleLend, $T) };
(&$lt:lifetime $T:ident) => { $crate::__lend_impl!(DynFallibleLendShunt, DynFallibleLend, &$lt $T) };
(&$lt:lifetime mut $T:ident) => { $crate::__lend_impl!(DynFallibleLendShunt, DynFallibleLend, &$lt mut $T) };
(&$lt:lifetime str) => { $crate::__lend_impl!(DynFallibleLendShunt, DynFallibleLend, &$lt str) };
(&$lt:lifetime mut str) => { $crate::__lend_impl!(DynFallibleLendShunt, DynFallibleLend, &$lt mut str) };
(&$lt:lifetime [$T:ident]) => { $crate::__lend_impl!(DynFallibleLendShunt, DynFallibleLend, &$lt [$T]) };
(&$lt:lifetime mut [$T:ident]) => { $crate::__lend_impl!(DynFallibleLendShunt, DynFallibleLend, &$lt mut [$T]) };
(Vec<$T:ident>) => { $crate::__lend_impl!(DynFallibleLendShunt, DynFallibleLend, Vec<$T>) };
(&$lt:lifetime Vec<$T:ident>) => { $crate::__lend_impl!(DynFallibleLendShunt, DynFallibleLend, &$lt Vec<$T>) };
(&$lt:lifetime mut Vec<$T:ident>) => { $crate::__lend_impl!(DynFallibleLendShunt, DynFallibleLend, &$lt mut Vec<$T>) };
(& &$lt:lifetime $T:ident) => { $crate::__lend_impl!(DynFallibleLendShunt, DynFallibleLend, & &$lt $T) };
(&&$lt:lifetime $T:ident) => { $crate::__lend_impl!(DynFallibleLendShunt, DynFallibleLend, &&$lt $T) };
(& &$lt:lifetime mut $T:ident) => { $crate::__lend_impl!(DynFallibleLendShunt, DynFallibleLend, & &$lt mut $T) };
(&&$lt:lifetime mut $T:ident) => { $crate::__lend_impl!(DynFallibleLendShunt, DynFallibleLend, &&$lt mut $T) };
(&$lt:lifetime ($($T:ident),+ $(,)?)) => { $crate::__lend_impl!(DynFallibleLendShunt, DynFallibleLend, &$lt ($($T),+)) };
(&$lt:lifetime mut ($($T:ident),+ $(,)?)) => { $crate::__lend_impl!(DynFallibleLendShunt, DynFallibleLend, &$lt mut ($($T),+)) };
(($($T:ident),+ $(,)?)) => { $crate::__lend_impl!(DynFallibleLendShunt, DynFallibleLend, ($($T),+)) };
($($tt:tt)*) => {
compile_error!(concat!(
"fallible_lend!() only accepts simple covariant patterns. ",
"For complex types, use covariant_fallible_lend!(Name = YourType) instead."
))
};
}