Impl + iterators + lifetimes, stuck

I have a simple function:

pub fn ls(&self, container: Option<i64>) -> Result<impl Iterator<Item = Record>, DatabaseErr> {
    let iter = try!(self.iter_child_ids(container)).map(|x| { self.read(x).unwrap().unwrap() });
    Ok(iter)
}

Compiling gives this error:

error[E0564]: only named lifetimes are allowed in impl Trait, but `` was found in the type std::iter::Map<impl std::iter::Iterator, [closure@database.rs:159:61: 159:99 self:&&database::Database]>

Which I understand to be because the closure borrows self, which has an implicit lifetime associated with it. However, I'm not sure how to fix this. I tried:

pub fn ls<'a>(&'a self, container: Option<i64>) -> Result<&'a impl Iterator<Item = Record>, DatabaseErr> {
    let iter = try!(self.iter_child_ids(container)).map(|x| { self.read(x).unwrap().unwrap() });
    Ok(&iter)
}

Hoping that maybe that would resolve it, but that results in the same error. Is there a way to do this? With local variables, a move closure generally resolves the problem, but not sure what to do when the closure needs access to self.

Looks like this works:

pub fn ls<'a>(&'a self, container: Option<i64>) -> Result<impl Iterator<Item = Record> + 'a, DatabaseErr> {
    let iter = try!(self.iter_child_ids(container)).map(move |x| { self.read(x).unwrap().unwrap() });
    Ok(iter)
}
2 Likes