为什么在将较高级别的特征边界与关联类型组合时会出现Rust编译错误



我正在编写一些涉及泛型特征和非'static类型的Rust代码,因此我遇到了近似泛型关联类型的需要。我知道GAT在当前的Rust中无法优雅地模拟,但我认为我已经找到了一个(不雅的(变通方法,可以适用于我的特定情况,使用具有寿命参数和更高等级特征边界的特征。然而,我收到了一些我不理解的编译器错误,关于关联类型的缺失特征实现。

下面的代码显示了一个重现错误的最小示例。

use std::fmt::Debug;
trait Resource<'r> {
type Value;
}
struct ResourceImpl();
impl<'r> Resource<'r> for ResourceImpl {
type Value = u32;
}
fn test_generic<R>()
where
for<'r> R: Resource<'r>,
for<'r> <R as Resource<'r>>::Value: Debug,
{
}
fn test_specific() {
test_generic::<ResourceImpl>();
}

当我尝试编译此代码(rustc1.41.0(时,我收到以下错误消息。

error[E0277]: `<ResourceImpl as Resource<'r>>::Value` doesn't implement `std::fmt::Debug`
--> src/lib.rs:21:5
|
13 | fn test_generic<R>()
|    ------------
...
16 |     for<'r> <R as Resource<'r>>::Value: Debug,
|                                         ----- required by this bound in `test_generic`
...
21 |     test_generic::<ResourceImpl>();
|     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `<ResourceImpl as Resource<'r>>::Value` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
|
= help: the trait `for<'r> std::fmt::Debug` is not implemented for `<ResourceImpl as Resource<'r>>::Value`

错误消息听起来像是说u32没有实现Debug,这是没有意义的。我一定误解了错误信息的意思,但我不知道实际的问题是什么

这个问题有一个悬而未决的问题。

在您的情况下,一种变通方法可以是将Debug绑定到关联的类型Resource::Value

trait Resource<'r> {
type Value: Debug;
}.
正如attdona所指出的,这似乎是一个编译器错误(这里有一个开放问题(。关于这个问题的讨论指向了这个堆栈溢出问题,它提供了一个对我有效的解决方法。解决方法的关键点是,在更高级别的特征界中提到的特征必须具有与for<_>中的寿命参数匹配的寿命参数。这可以通过创建一个具有所需生存期参数的包装特性(在本例中为Debug(来实现。

在问题中给出的最小示例的情况下,解决方法如下:

use std::fmt::Debug;
trait Resource<'r> {
type Value;
}
struct ResourceImpl();
impl<'r> Resource<'r> for ResourceImpl {
type Value = u32;
}
trait DebugWithLifetime<'r>: Debug {}
impl<'r, T> DebugWithLifetime<'r> for T where T: Debug {}
fn test_generic<R>()
where
for<'r> R: Resource<'r>,
for<'r> <R as Resource<'r>>::Value: DebugWithLifetime<'r>,
{
}
fn test_specific() {
test_generic::<ResourceImpl>();
}

最新更新