, более принципиальный решатель для типов проблем, которые создает сложная система типов.
фрагмент действителен в Rust 1.26.1:
use std::ops::AddAssign;
trait Trait
where
for<'a> Self: AddAssign<Self> + AddAssign<&'a Self> + Sized,
{
}
trait Trait2 {
type Associated: Trait;
fn method(u32) -> Self::Associated;
}
fn func<T2: Trait2>() {
let mut t = T2::method(1);
let t2 = T2::method(2);
t += &t2;
}
Заметить, чтоTrait
реализует обаAddAssign<Self>
а такжеAddAssign<&'a Trait>
(в том порядке, который важен позже). Поэтому вfunc
мы знаем, что обаt += t2
а такжеt += &t2
должно быть в силе. Как виднона площадке, t += &t2
действителен, нос помощьюt += t2
не:
error[E0308]: mismatched types
--> src/main.rs:19:10
|
19 | t += t2;
| ^^
| |
| expected reference, found associated type
| help: consider borrowing here: `&t2`
|
= note: expected type `&<T2 as Trait2>::Associated`
found type `<T2 as Trait2>::Associated`
Я читаю эту ошибку, так как компилятор не признает, чтоAddAssign<Self>
реализован дляT::Associated
, что явно неправильно, так как он реализуетTrait
, который требуетAddAssign<Self>
.
Если мы изменим порядокAddAssign
ограничиваетTrait
тогда верно обратное:t += t2
действует покаt += &t2
не.
Быстрое решение проблемы - сделатьfunc
общий по обоим признакам:
fn func<T: Trait, T2: Trait2<Associated = T>>() {
let mut t = T2::method(1);
let t2 = T2::method(2);
t += t2;
}
Это не должно быть необходимым; компилятор может распознать один изAddAssign
с, почему не другой? Кажется, последняя граница - это та, которую нужно признать.
Моим первым подозрением было то, что это как-то связано с динамической отправкой. Я исключил это, поскольку порядок границ не должен иметь значения даже при динамическом распределении. Я даже не думаю, что он использует его, так как все типы известны во время компиляции с использованием мономорфизации.
Мое текущее подозрение - ошибка компилятора, когда средство проверки типов не учитывает обобщенные элементы в границах признаков, когда это связанный тип. Легко представить, что такой конкретный случай упускается из виду.
Что здесь происходит?