限制未使用的泛型会导致编译错误

the*_*fer 6 rust

我不明白为什么限制未使用的泛型会导致编译错误。为什么会这样编译:

#[derive(PartialEq)]
struct B;

fn is_eq<T>(b: B, c: B) -> bool 
// where
//     B: PartialEq<T>,
{
    b == c
}
Run Code Online (Sandbox Code Playgroud)

但取消注释 where 子句会导致此编译错误:

error[E0308]: mismatched types
 --> src/lib.rs:9:10
  |
4 | fn is_eq<T>(b: B, c: B) -> bool
  |          - this type parameter
...
8 |     b == c
  |          ^ expected type parameter `T`, found `B`
  |
  = note: expected type parameter `T`
                     found struct `B`
Run Code Online (Sandbox Code Playgroud)

进行==显式编译,即PartialEq::<B>::eq(&b, &c)- 尽管编译器不应该清楚地使用此实现吗?奇怪的是,将输入参数更改为 &B 并使用==编译。很高兴知道为什么会出现错误以及这里发生了什么。

dre*_*ato 4

这个bug从Rust 1.0开始就存在:

另一种获取 和 的方法B == TB == B指定两者:

fn is_eq<T>(b: B, c: B) -> bool 
where
    B: PartialEq<T> + PartialEq<B>,
// also works: B: PartialEq<T> + PartialEq,
Run Code Online (Sandbox Code Playgroud)

当您使用 时&B,它通常会忽略您的 where 子句,因为您不再比较B值。相反,它通过毯子实现来获取参考,这显然足以找到PartialEq<B>

您可以通过更改 where 子句来使引用不被编译。

fn is_eq<T>(b: B, c: B) -> bool
where
    for<'a> &'a B: PartialEq<&'a T>,
{
    (&b) == (&c)
}
Run Code Online (Sandbox Code Playgroud)