簡體   English   中英

為什么在將高級特征邊界與關聯類型結合時會出現 Rust 編譯錯誤?

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

我正在編寫一些涉及泛型特征和非'static類型'static Rust 代碼,因此我遇到了近似泛型關聯類型的需要。 我知道在當前的 Rust 中無法優雅地模擬 GAT,但我認為我已經找到了一種(不優雅的)解決方法,它適用於我的特定情況,使用具有生命周期參數和更高等級特征邊界的特征。 但是,關於缺少關聯類型的特征實現,我遇到了我不明白的編譯器錯誤。

以下代碼顯示了重現錯誤的最小示例。

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

當我嘗試編譯此代碼 ( 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`

錯誤消息聽起來像是在說u32沒有實現Debug ,這是沒有意義的。 我一定誤解了錯誤消息的含義,但我無法弄清楚實際問題是什么。

有一個關於這個問題的公開問題。

在您的情況下,解決方法可能是將Debug綁定到關聯類型Resource::Value

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

正如 attdona 指出的那樣,這似乎是一個編譯器錯誤(這里有一個未解決的問題)。 關於這個問題的討論指向了這個 Stack Overflow 問題,它提供了一個對我有用的解決方法。 解決方法的關鍵點是在高階 trait bound 中提到的 trait 必須具有與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>();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM