Почему логический тип не является «транзитивным»? - PullRequest
0 голосов
/ 05 мая 2018

Когда я пытаюсь скомпилировать этот код:

use std::borrow::Borrow;

fn test_eq<T, U, B>(t: T, u: U) -> bool
where
    T: Borrow<B>,
    U: Borrow<B>,
    B: PartialEq<B> + ?Sized,
{
    t.borrow() == u.borrow()
}

fn main() {
    let my_vec = vec![1, 2, 3];

    assert!(test_eq(my_vec, [1, 2, 3]));
}

Я получаю:

error[E0283]: type annotations required: cannot resolve `std::vec::Vec<i32>: std::borrow::Borrow<_>`
  --> src/main.rs:15:13
   |
15 |     assert!(test_eq(my_vec, [1, 2, 3]));
   |             ^^^^^^^
   |

Очевидно, [T] является хорошим кандидатом на B, потому что:

  • Vec<T> реализует Borrow<[T]>
  • [T, 3] реализует Borrow<[T]>
  • [T] агрегатов PartialEq<[T]>

и мой код компилируется, если я явно указываю типы:

assert!(test_eq::<Vec<i32>, [i32; 3], [i32]>(my_vec, [1, 2, 3]));

Почему этот код не компилируется?

1 Ответ

0 голосов
/ 05 мая 2018

E0283

Эта ошибка возникает, когда у компилятора недостаточно информации, чтобы однозначно выбрать реализацию.

В этом примере компилятор не может сделать вывод, что B является типом среза [T]. Вы должны по крайней мере указать эту информацию с аннотацией [_]:

assert!(test_eq::<_, _, [_]>(my_vec, [1, 2, 3] ));
...