涉及关联类型的不满足特征界限

2023-12-22

The code

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 A<I> and A<bool>).

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

第 (1) 行或泛型类型成功I, so T::F : Q<bool>在这些情况下确实是假设的。

为什么第 (1) 行或泛型类型会自动假定特征边界,但第 (2) 行则不然?

我们可以修复上面的代码而不附加where T::F: Q<bool>每次我们使用T: A<I=bool>?


从 Rust 1.18 开始,编译器要求您编写这些边界,以便类型格式良好的。基本上,为了边界T: A<I = bool>要保持,则需要有界T::F: Q<bool>也成立。例如,如果某种类型尝试实现A像这样:

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<bool>不成立(事实上,编译器给出了一个错误impl)。但令人沮丧的是,目前,界限T::F: Q<bool>每当边界时必须明确给出T: A<I = bool>出现。在某种程度上,它让编译器放心,嘿,T::I = bool那里也有!

为什么第 (1) 行或泛型类型会自动假定特征边界,但第 (2) 行则不然?

对于第 (1) 行,界限为T::F: Q<T::I>,即恰恰的要求A (with T替代Self)。事实上,我们也可以将边界等效地写成这样:

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

对于第 (2) 行,边界T::F: Q<bool>可能看起来只是更换的问题T::I with bool,但这种差异对编译器很重要;T::I是一个关联类型,而bool是具体类型。


Rust 开发人员正在考虑改进编译器,以便不必在各处重复这样的界限让编译器推断这些界限 https://internals.rust-lang.org/t/lang-team-minutes-implied-bounds/4905.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

涉及关联类型的不满足特征界限 的相关文章

随机推荐