rusttreesitter

Lifetimes and IntoIter in Rust


I was working on some rust utilities for the rust tree sitter bindings. Tree sitter essentially parses some code and creates an abstract syntax Tree. This tree consists of Nodes representing structures of code (e.g. csharp classes) and can be traversed using a TreeCursor

I wanted to extend the existing functionality by implementing some wrapper types which I called ExtendedTree, ExtendedTreeCursor and ExtendedNode.

One of the convenience functions I wanted to try and implement, was that I could access the source-code which was used for creating the Extended-classes from all of the classes. This source code should not change throughout the apllication runtime and I stored it as a source: Rc<&str>. Since it is a reference it required a lifetime, which I called 's.

Additionally, TreeCursor and Node have a lifetime, which I called 't. The Tree does not need a lifetime, so ExtendedTree also only has lifetime 's and no 't.

I wanted to implement a way to create an ExtendedCursor from a &'t ExtendedTree, which I managed to do:

fn get_cursor<'t>(self: &'t Self) -> ExtendedTreeCursor<'t, 's>
where
    's: 't,
{
    ExtendedTreeCursor::new(
        self.ts_tree.root_node().walk(),
        &self.get_complete_source().clone(),
    )
}

But then I remembered, that there is a IntoIterator trait, which should be more elegant.

I did not manage to implement IntoIterator though. My best attempt is:

impl<'t, 's> IntoIterator for ExtendedTree<'s>
where
    's: 't,
{
    type Item = ExtendedNode<'t, 's>;
    type IntoIter = ExtendedTreeCursor<'t, 's>;

    fn into_iter(self) -> Self::IntoIter {
        ExtendedTreeCursor::new(
            self.ts_tree.root_node().walk(),
            &self.get_complete_source().clone(),
        )
    }
}

It causes the following error:

error[E0207]: the lifetime parameter `'t` is not constrained by the impl trait, self type, or predicates
  --> src\tree_extensions\extended_tree.rs:47:6
   |
47 | impl<'t, 's> IntoIterator for ExtendedTree<'s>
   |      ^^ unconstrained lifetime parameter.

Note: removing 't causes undeclared lifetimes for type Item below.

I wonder what I am doing wrong and if it is even possible to implement IntoIterator with the lifetimes 't and 's.

Note: I did manage to implement Iterator for ExtendedTreeCursor<'t, 's>.

You can find my complete code here, or specifically:


Solution

  • The solution was to add the lifetime in the in the trait impl as kmdreko suggested:

    impl<'t, 's> IntoIterator for &'t ExtendedTree<'s>
                                  ^^^
    

    I overlooked that the Self in the fn into_iter(self) is actually a reference.

    I have also changed the type of source to a more manageable String as
    Chayim Friedman suggested