Estou tentando implementar a marcação vitalícia como demonstrada neste playground, mas me perdi em algum lugar e não consigo descobrir o que fiz de errado.
Aqui está o erro que estou recebendo. Ele só aparece se a v.pup(...)
linha estiver lá.
error[E0597]: `arena` does not live long enough
--> src/lib.rs:65:5
|
64 | let arena = goop::Parent;
| ----- binding `arena` declared here
65 | arena.scope(|child, context| {
| -^^^^
| |
| _____borrowed value does not live long enough
| |
66 | | let mut v = Foo::new(child);
67 | | v.pup(context);
68 | | });
| |______- argument requires that `arena` is borrowed for `'static`
69 | }
| - `arena` dropped here while still borrowed
Aqui está meu código, o mais minimalista que consegui fazer:
#![no_std]
mod goop {
use core::marker::PhantomData;
// Cell<T> is invariant in T; so Cell<&'id _> makes `id` invariant.
// This means that the inference engine is not allowed to shrink or
// grow 'id to solve the borrow system.
type Id<'id> = PhantomData<::core::cell::Cell<&'id mut ()>>;
#[derive(Clone, Copy)]
pub struct Child<'id> {
_id: Id<'id>,
}
pub struct Parent;
#[derive(Clone, Copy)]
pub struct Context<'id, 'p> {
_id: Id<'id>,
parent: &'p Parent,
}
impl Parent {
pub fn scope<'p, F>(&'p self, _f: F)
where
F: for<'id> FnOnce(Child<'id>, Context<'id, 'p>)
{}
fn internal_something(&self) {}
}
pub trait Gator<C> {
fn gate(&self, c: C);
}
impl<'p, 'id> Gator<Context<'p, 'id>> for Child<'id> {
fn gate(&self, c: Context<'p, 'id>) {
c.parent.internal_something();
}
}
}
use core::marker::PhantomData;
struct Foo<C, G> {
_c: PhantomData<C>,
g: G,
}
impl<C, G: goop::Gator<C>> Foo<C, G> {
fn new(g: G) -> Self {
Self {
_c: PhantomData,
g,
}
}
fn pup(&mut self, c: C) {
self.g.gate(c)
}
}
fn _check() {
let arena = goop::Parent;
arena.scope(|child, context| {
let mut v = Foo::new(child);
v.pup(context);
});
}