I had the idea to use a pinus::sync::PineMap (GitHub) to make all references of equivalent objects actually reference the same object in memory (the "one" object would be a PineMap-owned value). I'm trying out PineMap
for this because its insert
will not move its items in memory (its insert borrows &self
not &mut self
too) so references to its values will stay valid even when adding more entries to the PineMap, and I can build self-referential items.
I have some kind of lifetimes issue:
#[derive(Eq, PartialEq, Ord, PartialOrd)]
enum List<'a> {
Cons(isize, &'a List<'a>),
Nil,
}
fn main() {
use List::*;
use pinus::{prelude::*, sync::PineMap};
let mut table = PineMap::new();
table.insert(Nil, Nil);
{
let nil = table.get(&Nil).unwrap();
table.insert(Cons(1, nil), Cons(1, nil));
}
table.clear();
}
error[E0597]: `table` does not live long enough
--> src/main.rs:13:19
|
13 | let nil = table.get(&Nil).unwrap();
| ^^^^^^^^^^^^^^^ borrowed value does not live long enough
...
17 | }
| -
| |
| `table` dropped here while still borrowed
| borrow might be used here, when `table` is dropped and runs the `Drop` code for type `PineMap`
error[E0502]: cannot borrow `table` as mutable because it is also borrowed as immutable
--> src/main.rs:16:5
|
13 | let nil = table.get(&Nil).unwrap();
| --------------- immutable borrow occurs here
...
16 | table.clear();
| ^^^^^^^^^^^^^ mutable borrow occurs here
17 | }
| - immutable borrow might be used here, when `table` is dropped and runs the `Drop` code for type `PineMap`
I thought declaring nil
in an inner scope would have resolved all my lifetime problems, because I understand this makes it have a shorter lifetime than table
, so it shouldn't be borrowing table
anymore by the time table
itself goes out of scope.
Why does it look like the inner variable is borrowing an outer variable for longer than the inner variable is in scope?
And in general if this is an unfixable approach, how might I be able to solve my original problem of collecting lots of references to the same object based on object equivalency? If an object O is created, I want to look up "has O been seen before?" If it has, then get a reference to the "cached" O, if it has not, then cache it and be the first to get a reference to the newly cached object.