Этот фрагмент действителен в 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
s, почему не другой?Кажется, последний предел - это тот, который должен быть распознан.
Мое первое подозрение было то, что это как-то связано с динамической диспетчеризацией.Я исключил это, поскольку порядок границ не должен иметь значения даже при динамическом распределении.Я даже не думаю, что он использует его, так как все типы известны во время компиляции с использованием мономорфизации.
Мое текущее подозрение - это ошибка компилятора, когда средство проверки типов не учитывает обобщения в границах признаков, когда оносвязанный тип.Легко представить, что такой конкретный случай упускают из виду.
Что здесь происходит?