不满意的 trait bound 涉及关联类型 [英] Unsatisfied trait bound involving associated type

查看:38
本文介绍了不满意的 trait bound 涉及关联类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

代码

pub trait Q<S> {
    fn f();
}

pub trait A {
    type I;
    type F: Q<Self::I>;
}

// this works (1)
//
// pub struct S<T>
// where
//     T: A
// {                 

// unsatisfied trait bound (2)
pub struct S<T>                                  
where
    T: A<I = bool>,
{

    t: T,
}

编译失败:

error[E0277]: the trait bound `<T as A>::F: Q<bool>` is not satisfied
  --> src/main.rs:18:1
   |
18 | / pub struct S<T>                                  
19 | | where
20 | |     T: A<I = bool>,
21 | | {
22 | |     t: T,
23 | | }
   | |_^ the trait `Q<bool>` is not implemented for `<T as A>::F`
   |
   = help: consider adding a `where <T as A>::F: Q<bool>` bound
   = note: required by `A`

有趣的是,如果您使用注释掉的行 (1) 而不是 (2),它会起作用.如果您将关联类型 I 转换为泛型类型(编写 trait AA),它也适用.

Interestingly, it works if you use the commented out line (1) instead of (2). It also works if you turn the associated type I into a generic type (write trait A<I> and A<bool>).

impl<T> S<T>
    where T: A
{
    fn g() {
        T::F::f()
    }
}

以第 (1) 行或泛型类型 I 成功,因此在这些情况下确实假定 T::F : Q.

succeeds with line (1) or generic type I, so T::F : Q<bool> is indeed assumed in those cases.

为什么第 (1) 行或泛型类型会自动假设 trait bound,而不是第 (2) 行?

Why is the trait bound automatically assumed with line (1) or generic types, but not with line (2)?

我们可以在每次使用T:A时不附加where T::F:Q来修复上面的代码吗?>

Can we fix the above code without appending where T::F: Q<bool> every time we use T: A<I=bool>?

推荐答案

从 Rust 1.18 开始,编译器要求您编写这些边界,以便类型格式良好.基本上,为了使绑定的 T:A 成立,需要绑定的 T::F:Q 也成立.例如,如果某种类型试图像这样实现 A:

As of Rust 1.18, the compiler requires you to write these bounds in order for the types to be well-formed. Basically, in order for the bound T: A<I = bool> to hold, it is required that the bound T::F: Q<bool> also holds. For example, if some type tried to implement A like this:

struct Y;
struct Z;

impl A for Y {
    type I = bool;
    type F = Z; // Z does not implement Q<bool>
}

then Y 不会是良构的,因为绑定的 T::F: Q 不成立(实际上,编译器给出了一个impl 上的错误).但令人沮丧的是,目前,每当绑定 T: A 出现时,必须明确给出绑定的 T::F:Q.在某种程度上,它让编译器放心,嘿,T::I = bool 也在那里!

then Y would not be well-formed, because the bound T::F: Q<bool> doesn't hold (and indeed, the compiler gives an error on the impl). But frustratingly, for now, the bound T::F: Q<bool> must be given explicitly whenever the bound T: A<I = bool> appears. In some way, it reassures the compiler that, hey, T::I = bool there too!

为什么第 (1) 行或泛型类型会自动假设 trait bound,而不是第 (2) 行?

Why is the trait bound automatically assumed with line (1) or generic types, but not with line (2)?

在第 (1) 行中,边界将是 T::F: Q,这正是A 的要求(用 T 代替 Self).事实上,我们也可以像这样写边界:

With line (1), the bound would be T::F: Q<T::I>, which is precisely the requirement of A (with T substituted for Self). Indeed, we can also write the bound equivalently like this:

pub trait A
where
    Self::F: Q<Self::I>,
{
    type I;
    type F;
}

在第 (2) 行中,绑定的 T::F:Q 可能看起来只是将 T::I 替换为 bool,但这种差异对编译器很重要;T::I 是关联类型,而 bool 是具体类型.

With line (2), the bound T::F: Q<bool> may look like it's just a matter of replacing T::I with bool, but that difference is important to the compiler; T::I is an associated type, while bool is a concrete type.

Rust 开发人员正在考虑改进编译器,这样就不必到处重复这样的界限了 让编译器推断这些界限.

The Rust developers are considering improving the compiler so that bounds like this don't have to have to be repeated all over the place by having the compiler infer those bounds.

这篇关于不满意的 trait bound 涉及关联类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆