I am currently trying to wrestle with the Lending Iterator problem as practice to improve my (poor) understanding of the borrow checker and I've run into quite a head-scratch-er that I can't figure out for the life of me.
Does anyone have any idea what I'm doing wrong, or is this one of those Polonius > NLL kind of things?
I see that lending-iterator also does not have a generically-implemented IntoLendingIterator, so this might be a repeat question, sorry if that's the case.
FYI: I do have a somewhat-working HKT trait to bind lifetimes without the hacky-workaround that lending-iterator and polonius-the-crab use, but it causes really bad lifetime poising in usage.
pub trait Lender {
type Lend<'lend>: 'lend
where
Self: 'lend;
fn next<'next>(&'next mut self) -> Option<<Self as Lender>::Lend<'next>>;
}
pub trait IntoLend {
type Lend<'lend>: 'lend
where
Self: 'lend;
}
pub trait IntoLender: IntoLend
where
for<'any> <Self as IntoLender>::Lender<'any>:
Lender<Lend<'any> = <Self as IntoLend>::Lend<'any>>,
{
type Lender<'lender>: 'lender
where
Self: 'lender;
fn into_lender<'s>(self) -> <Self as IntoLender>::Lender<'s>
where
Self: 's;
}
impl<P: Lender> IntoLend for P {
type Lend<'lend> = <Self as Lender>::Lend<'lend> where Self: 'lend;
}
impl<P: IntoLend> IntoLender for P
where
for<'any> Self: 'any + Lender<Lend<'any> = <Self as IntoLend>::Lend<'any>>,
{
type Lender<'lender> = Self where Self: 'lender;
#[inline]
fn into_lender<'s>(self) -> Self
where
Self: 's,
{
self
}
}
fn main() {
let mut x = 42u32;
let _ = __test(&mut x);
}
fn __test<'x>(x: &'x mut u32) {
/// MRE for Lender
struct Bar<'baz, Baz: 'baz>(&'baz mut Baz);
impl<'baz, Baz: 'baz> Lender for Bar<'baz, Baz> {
type Lend<'lend> = &'lend mut Baz where Self: 'lend;
fn next<'next>(&'next mut self) -> Option<<Self as Lender>::Lend<'next>> {
Some(&mut self.0)
}
}
// use MRE Lender
{
let mut bar: Bar<'x, u32> = Bar(x);
let _ = bar.next();
let _ = bar.next();
// ????????????????????????????????????????????????????????
let _ = <Bar<'x, u32> as IntoLender>::into_lender(bar);
// ????????????????????????????????? ^^^^^^^^^^^ ??????????
let _ = 0;
}
()
}
Errors:
Compiling playground v0.0.1 (/playground)
error: lifetime may not live long enough
--> src/lib.rs:56:17
|
43 | fn __test<'x>(x: &'x mut u32) {
| -- lifetime `'x` defined here
...
56 | let _ = <Bar<'x, u32> as IntoLender>::into_lender(bar);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'x` must outlive `'static`
error: could not compile `playground` due to previous error