简体   繁体   English

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

[英]Why do I get a Rust compilation error when combining higher-rank trait bounds with associated types?

I am writing some Rust code that involves generic traits and non- 'static types, and as a result I have come across the need to approximate generic associated types .我正在编写一些涉及泛型特征和非'static类型'static Rust 代码,因此我遇到了近似泛型关联类型的需要。 I understand that GATs can't be emulated elegantly in current Rust, but I thought I had figured out an (inelegant) workaround that would work for my specific situation, using traits with lifetime parameters and higher-rank trait bounds.我知道在当前的 Rust 中无法优雅地模拟 GAT,但我认为我已经找到了一种(不优雅的)解决方法,它适用于我的特定情况,使用具有生命周期参数和更高等级特征边界的特征。 However, I am getting compiler errors that I don't understand, regarding missing trait implementations for associated types.但是,关于缺少关联类型的特征实现,我遇到了我不明白的编译器错误。

The following code shows a minimal example that reproduces the error.以下代码显示了重现错误的最小示例。

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>();
}

When I try to compile this code ( rustc 1.41.0), I get the following error message.当我尝试编译此代码 ( rustc 1.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`

The error message sounds like it is saying u32 doesn't implement Debug , which wouldn't make sense.错误消息听起来像是在说u32没有实现Debug ,这是没有意义的。 I must be misunderstanding what the error message means, but I can't figure out what the actual problem is.我一定误解了错误消息的含义,但我无法弄清楚实际问题是什么。

There is an open issue about this problem.有一个关于这个问题的公开问题。

In your case a workaround could be to bind Debug to the associated type Resource::Value ?在您的情况下,解决方法可能是将Debug绑定到关联类型Resource::Value

trait Resource<'r> {
    type Value: Debug;
}.

As attdona pointed out, this appears to be a compiler bug (with an open issue here ).正如 attdona 指出的那样,这似乎是一个编译器错误(这里有一个未解决的问题)。 The discussion on that issue points to this Stack Overflow question , which provides a workaround that worked for me.关于这个问题的讨论指向了这个 Stack Overflow 问题,它提供了一个对我有用的解决方法。 The key point of the workaround is that the trait mentioned inside the higher-rank trait bound must have lifetime parameters matching those inside the for<_> .解决方法的关键点是在高阶 trait bound 中提到的 trait 必须具有与for<_>生命周期参数匹配的生命周期参数。 This can be achieved by creating a wrapper trait (in this case around Debug ) with the required lifetime parameters.这可以通过使用所需的生命周期参数创建包装特征(在这种情况下围绕Debug )来实现。

In the case of the minimal example given in the question, the workaround looks like this:在问题中给出的最小示例的情况下,解决方法如下所示:

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>();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Rust,serde 反序列化和更高等级的特征界限 <`a> - Rust, serde Deserialize and Higher Rank Trait Bounds For<`a> 如何使用更高等级的特征边界使返回的 impl Fn 更通用? - How to use higher-rank trait bounds to make a returned impl Fn more generic? 扩展失败类型的结果时,为什么会得到“该方法存在,但以下特征范围不满足”的信息? - Why do I get “the method exists but the following trait bounds were not satisfied” when extending Result for failure types? Rust 特征边界与类型 - Rust trait bounds with types 整数类型的 Rust 特征边界 - Rust trait bounds for integral types 当使用ReadBytesExt从字节片中读取整数时,为什么会出现错误“特征边界未得到满足”? - Why do I get the error “trait bounds were not satisfied” when using ReadBytesExt to read an integer from a slice of bytes? 为什么我在使用连接时得到 Vec&lt;&amp;&amp;str&gt; 的“不满意的特征界限”? - Why do I get "unsatisfied trait bounds" for a Vec<&&str> when using join? 为什么在特化特征时出现冲突的实现错误? - Why do I get a conflicting implementations error when specializing a trait? 如何消除特征对象边界中关联类型的歧义? - How to disambiguate associated types in trait object bounds? 具有关联类型的特征对象中的 Rust 多态性 - Rust polymorphism in trait objects with associated types
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM