Hi!
I need to have a tree-like data structure, where every node is the same type, and where each child references it's parent. I tried different things, and eventually found one working, but I can't tell why it's working.
Some minimal example code is here in the playground.
Temporary references are a wrong feature for this.
Self-referential structures are not allowed by the borrow checker in any way. Such cyclic dependency won't work in any useful way.
Rust references are forbidden from storing data, by design. They are for borrowing data, which by definition is the opposite of owning (storing, permanently holding) data. &Child in a Tree struct is a promise that the Child object is not stored in the Tree. If you're hoping to make this a data structure holding tree nodes, then it's promising the opposite of what you want.
You should use owned objects (remove all &). Use Rc or Arc to have pointer indirection, and Weak to have a parent pointer if you must.
Alternatively, store all nodes in an arena, and then build a tree out of references into the arena (this will be limited to living in a scope where the arena lives, so it's suited for temporary trees that won't be stored/returned into larger scope). Arena implementation details require unsafe code, but you can find existing crates implementing it.
It probably still doesn't actually work in a useful way. The nested lifetimes, along with recursively swapping the left and right parameters, means that you still have something akin to your other attempt:
Is because you used the Self alias, which is aliasing Tree<'parent>exactly, meaning you would have to have a &'parent Tree<'parent> to pass in. Making self: &'parent Self is one way to make it compile, or you could instead use Tree::Child instead of Self::Child.
However, chances are low that you actually want something like this in practice, for the reasons @kornel outlined. (Just because it compiles doesn't mean it will be useful.)
I finally found the solution, as quinedot mentioned:
That's something I had in mind with the return type, but not the actual enum construction.
I will use this solution, rather than an arena, because this tree is not meant for storage nor runtime flexibility. The entire tree structure will be stored in the stack, and lifetimes will be predictable, hardcoded. There will be no self-references, because the parents and the childs will be owned by the current scope, in the stack (the parent will never own the child).