Amanieu / intrusive-rs

Intrusive collections for Rust
Apache License 2.0
400 stars 47 forks source link

Borrow check failures for complex structures #64

Open jleahy opened 2 years ago

jleahy commented 2 years ago

It's likely this is more a misunderstanding than a real issue, however the following gives borrow checker failures despite being seemingly legitimate according to the documentation.

This is the sort of thing you might do if you wanted to represent a tree, where a head node had a set of children, each of those has grandchildren and so forth.

use intrusive_collections::{SinglyLinkedListLink, SinglyLinkedList, intrusive_adapter};
use typed_arena::Arena;

pub struct Thing<'a> {
    link: SinglyLinkedListLink,
    list: SinglyLinkedList<Adapter<'a>>,
}
intrusive_adapter!(Adapter<'a> = &'a Thing<'a>: Thing<'a> { link: SinglyLinkedListLink });

pub fn foo<'a>(_: &'a Arena<Thing<'a>>) {
}

#[test]
fn bar() {
    let arena = Arena::new();
    foo(&arena);
}

This gives the following output:

error[E0597]: `arena` does not live long enough
  --> test.rs:17:9
   |
17 |     foo(&arena);
   |         ^^^^^^ borrowed value does not live long enough
18 | }
   | -
   | |
   | `arena` dropped here while still borrowed
   | borrow might be used here, when `arena` is dropped and runs the destructor for type `Arena<Thing<'_>>`

For more information about this error, try `rustc --explain E0597`.

Plausibly this is related to what's going on inside intrusive_adapter.

Amanieu commented 2 years ago

I looked into this and we seem to be hitting a limitation of Rust's borrow checking system. I'm not sure if it's possible to resolve it.