#Mutable lifetimes help

4 messages · Page 1 of 1 (latest)

boreal thistle
#
#![feature(option_get_or_insert_default)]

use generic_array::{ArrayLength, GenericArray};

pub trait Prefix: Copy {
    type Count: ArrayLength;

    fn index(&self) -> usize;
}

/// Trie implementation
pub struct PrefixTree<T: Prefix> {
    children: GenericArray<Option<Box<Self>>, T::Count>,
    end: bool,
}

struct WalkMut<'a, T: Prefix, I: Iterator<Item = usize>> {
    node: &'a mut PrefixTree<T>,
    indices: I,
}

impl<'a, T: Prefix, I: Iterator<Item = usize>> Iterator for WalkMut<'a, T, I> {
    type Item = Option<&'a mut PrefixTree<T>>;

    fn next(&mut self) -> Option<Self::Item> {
        let index = self.indices.next()?;
            
        if let Some(child) = self.node.children[index].as_deref_mut() {
            self.node = child;
            Some(Some(self.node))
        } else {
            Some(None)
        }
    }
}

impl<T: Prefix> PrefixTree<T> {
    #[must_use]
    fn walk_mut<I: IntoIterator<Item = usize>>(&mut self, indices: I) -> WalkMut<'_, T, I::IntoIter> {
        WalkMut {
            node: self,
            indices: indices.into_iter(),
        }
    }
}

I'm writing a prefix tree and currently implementing a walk iterator to allow walking the tree via indices. The non-mutable Walk iterator works however the mutable WalkMut iterator fails to compile due to compiler errors. Here's all the code: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=6ec2b843e130b627c6dca20ba5b1ec28

error: lifetime may not live long enough
  --> src/lib.rs:60:13
   |
44 | impl<'a, T: Prefix, I: Iterator<Item = usize>> Iterator for WalkMut<'a, T, I> {
   |      -- lifetime `'a` defined here
...
54 |     fn next(&mut self) -> Option<Self::Item> {
   |             - let's call the lifetime of this reference `'1`
...
60 |             Some(Some(self.node))
   |             ^^^^^^^^^^^^^^^^^^^^^ method was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
earnest panther
#

you see, returning &mut PrefixTree<T> as the items can't work, because by calling next() twice on the iterator you would get 2 mutable references to the same thing

#

because you'd have both &mut parent and &mut child