我正在尝试实现像这个操场上演示的那样的终身标记,但是我在某些地方误入歧途并且无法弄清楚我做错了什么。
这是我遇到的错误。只有当该v.pup(...)
行存在时才会出现。
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
这是我的代码,这是我能做到的尽可能简单的代码:
#![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);
});
}
在这里
impl
你交换了生命周期Context
:此错误与
v.pup(context)
调用相结合,导致编译器推断'p
和'id
必须具有完全相同的生命周期。由于程序中的其他约束,唯一可以满足此要求的方法是两者都是'static
,因此编译器会假设这一点。该假设会导致您看到的错误。这是一个归谬法的例子,但你只能看到最后的冲突步骤,而不是导致这一步骤的逻辑链。
交换它们,代码就可以编译了:
(游乐场)