为什么类似 Deref 的特征不能组合?

apt*_*002 4 traits lifetime rust borrow-checker

在此代码中,匹配标准库中MyDeref的定义,并且(从更复杂的示例简化)几乎也匹配。DerefMemoryView

pub trait MyDeref {
    type Target: ?Sized;
    fn deref<'a>(&'a self) -> &'a Self::Target;
}

pub trait MemoryView {
    type T;
    fn at_ref<'a>(&'a self) -> &'a Self::T;
}
Run Code Online (Sandbox Code Playgroud)

我期望这些特征能够组合起来,这样我就可以编写一个MemoryView覆盖任何取消引用 a 的类型的全面实现MemoryView

impl<V: MemoryView, T: MyDeref<Target=V>> MemoryView for T {
    type T = V::T;
    fn at_ref<'a>(&'a self) -> &'a Self::T {
        self.deref().at_ref()
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我收到编译器错误:

error[E0309]: the parameter type `V` may not live long enough
  --> src/lib.rs:14:9
   |
14 |         self.deref().at_ref()
   |         ^^^^^^^^^^^^ ...so that the type `V` will meet its required lifetime bounds
Run Code Online (Sandbox Code Playgroud)

似乎是在说方法签名暗示着并且Self寿命Self::T长于'a,但并不是Self::Target寿命长于a

我很难想象 a 的Self::Target寿命怎么可能比Self. Deref对于明显的类型,例如&'a Target和,这是不可能的Box<Target>

我也在努力写出某种特征界限,表明Self::Target寿命比 更长Self

这种全面实施感觉应该是可能的。帮助!

cdh*_*wie 7

这是其中一种情况,您做错了一些事情,导致编译器非常困惑,以至于建议您做一些无助于解决根本问题的事情。

您可以使用(否则不必要的)生命周期 GAT 来消除此错误,然后编译器可以揭示真正的问题:V在实现中不受限制MemoryView for T。因为V不受约束,所以编译器无法真正看到它与其他生命周期有何关系,从而推断出适当的生命周期V......即使您可以解决这个问题,无论如何也不能拥有不受约束的泛型类型参数,因此它是一个有争议的问题。

解决方案是完全删除该V参数。您在这里使用它的唯一原因是您可以要求T::Target实现MemoryView- 因此只需添加该绑定,然后type T相应地调整实现:

impl<T> MemoryView for T
where
    T: MyDeref,
    <T as MyDeref>::Target: MemoryView,
{
    type T = <<T as MyDeref>::Target as MemoryView>::T;

    fn at_ref<'a>(&'a self) -> &'a Self::T {
        self.deref().at_ref()
    }
}
Run Code Online (Sandbox Code Playgroud)

游乐场