Amanieu / intrusive-rs

Intrusive collections for Rust
Apache License 2.0
412 stars 48 forks source link

Deal with lifetime issue of stack varaibles #85

Closed npuichigo closed 1 year ago

npuichigo commented 1 year ago

Thank you for this fantastic job. I'm looking for some solution to use intrusive linked list together with variables on stack.

In the document, it's needed to make the elements outlive the linked list to meet the requirements of rust.

// We can also insert stack allocated values into an intrusive list.
// Again, the values must outlive the LinkedList.
let a = Value {
    link: LinkedListLink::new(),
    value: Cell::new(4),
};
let b = Value {
    link: LinkedListLink::new(),
    value: Cell::new(5),
};
let c = Value {
    link: LinkedListLink::new(),
    value: Cell::new(6),
};
let mut list2 = LinkedList::new(ValueAdapter::new());
list2.push_back(&a);
list2.push_back(&b);
list2.push_back(&c);
assert_eq!(list2.iter().map(|x| x.value.get()).collect::<Vec<_>>(), [4, 5, 6]);

But I think it's too restrict in real world. For example, after the item is poped from the linked list, it can be droped ealier before the linked list. And it's often the case to use LinkedList as a task queue in thread pool.

I could use arena as an wordaround, but it's not so intuitive.

Amanieu commented 1 year ago

This is a limitation of Rust's lifetimes: the LinkedList can only track a single lifetime, and it must outlive the LinkedList type itself. The alternative is dynamic allocation which avoids using Rust's lifetimes.

npuichigo commented 1 year ago

https://github.com/tokio-rs/tokio/blob/92d33b718142b1f952aef5ab9e3b09adb0a26548/tokio/src/sync/notify.rs#L1072 The internal intrusive linked list implementation of tokio has support to use NonNull for tracing linked nodes which avoids use reference with lifetime. Would that be supported here?

Amanieu commented 1 year ago

Tokio's intrusive linked list has an unsafe API, which relies on the user to check that the lifetimes are correct. You can do the same with this crate by using the UnsafeRef type which ignores lifetimes.

npuichigo commented 1 year ago

Thanks😀