IterMut: cannot infer an appropriate lifetime

Hi, I'm trying to implement iter_mut for an struct that represents a linked list and contains a reference to a pool of elements, but I am having a problem with:

cannot infer an appropriate lifetime for autoref due to conflicting requirements

After reading different answers in internet (for example this) I can understand why is it failing. But I can not figure out how to do it right.

This code has to work with no-std, that's why I'm implementing my own pool. The purpose of the Modulations struct is to handle multiple linked lists using a single pool of elements, while ParamModulationsMut represents a mutable view to a single linked list.

The problem is reproduced here:

I'd appreciate if someone could help me figure out a solution to provide a mutable iterator for ParamModulationsMut.

Thanks in advance!

Implementing mutable iterators by hand can rarely be done without unsafe code, so reuse the unsafe code someone else has already written:

impl<'a> ParamModulationsMut<'a> {
    ...
    pub fn iter_mut<'b>(&'b mut self) -> IterMut<'b> {
        IterMut {
            iter: self.pool.elements.as_mut_slice()[self.head..].iter_mut(),
        }
    }
}

pub struct IterMut<'a> {
    iter: std::slice::IterMut<'a, Node<Modulation>>,
}
impl<'a> Iterator for IterMut<'a> {
    type Item = &'a mut Modulation;

    fn next(&mut self) -> Option<Self::Item> {
        match self.iter.next() {
            None => None,
            Some(node) => Some(&mut node.data),
        }
    }
}

Note also that I changed how the lifetimes work on the iter_mut method. You never want to take the generic lifetime on the struct itself and put it on &mut self as that makes the method near-impossible to use.

Thanks @alice, that's good advice. In my specific case, I'd need to go into unsafe world then, because there is no underlying iterator I could use.
But I think I'll try to re-think the whole design to avoid it.
Best.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.