这个更高级别的特征界限是什么意思?

What does this higher-ranked trait bound mean?

在 Salsa 中,有一个更高级别的特征绑定到一个特征上。我在功能定义上看到了 HRTB,但在特征上没有看到。这是什么意思?

pub trait Query: Debug + Default + Sized + for<'d> QueryDb<'d> {
...
    fn query_storage<'a>(
        group_storage: &'a <Self as QueryDb<'_>>::GroupStorage,
    ) -> &'a Arc<Self::Storage>;
}

https://github.com/salsa-rs/salsa/blob/fc6806a/src/lib.rs#L370

如题,我该如何阅读?是不是说,对于任何 Query,都有一个对应的 QueryDB 一些 生命周期?

这与

有何不同
pub trait Query<'d>: Debug + Default + Sized + QueryDb<'d>

除此之外,impls 无法指定 'd?

query_storage的参数类型有关:

Self as QueryDb<'_>

来自小说:

for<'a> can be read as "for all choices of 'a", and basically produces an infinite list of trait bounds that F must satisfy.

https://doc.rust-lang.org/nomicon/hrtb.html

how should I read this?

这意味着 Query 的任何实现也同时为 'd 的所有可能值(即所有生命周期)实现 QueryDb<'d> .因此,在一般情况下,特征界限 T: Query 意味着 T: for<'d> QueryDb<'d>.

How is this different from

pub trait Query<'d>: Debug + Default + Sized + QueryDb<'d>

aside from that impls cannot specify 'd?

通过在 Query 上重复生命周期参数,这意味着所有特征边界 T: Query 都需要更改为 T: for<'d> Query<'d> 以等效于 HRTB 所在的版本在 Query 本身。

这基本上就是a workaround for the lack of generic associated types。对于泛型关联类型,QueryDb 看起来像这样:

pub trait QueryDb: Sized {
    /// Dyn version of the associated trait for this query group.
    type DynDb<'d>: ?Sized + Database + HasQueryGroup<Self::Group> + 'd;

    /// Associate query group struct.
    type Group: plumbing::QueryGroup<GroupStorage = Self::GroupStorage>;

    /// Generated struct that contains storage for all queries in a group.
    type GroupStorage;
}

在引入此生命周期参数的 pull request 之前,QueryDb 不是一个单独的特征;它的成员是 Query 的一部分。通用关联类型将允许我们将 QueryDb 合并回 Query.

在阅读了关于那个 pull request 的评论后,我觉得这个改变没有产生预期的结果。目标是在关联类型 DynDb 上允许与隐含的 'static 不同的界限,但是由于每个 Query 为所有可能的 'd 实现 QueryDb<'d>,这意味着每个 Query 实施 QueryDb<'static>。因此,在 QueryDb 的所有实现中,DynDb 不可能借用任何生命周期短于 'static 的东西,否则 Query 的实现将不被允许(边界for<'d> QueryDb<'d> 不会满意)。