Can Add::Output be smarter?


#1

I’ve ran into problem that was hard to figure out, and it resulted in pretty ugly syntax. It boils down to:

  1. The Add trait’s Output isn’t automatically deduced
  2. type can’t simply refer to its own name

I started with:

pub trait Tr {
    type Distance: PartialOrd + Add;
}

fn foo<T: Tr>(a: <T as Tr>::Distance, b: <T as Tr>::Distance, c: <T as Tr>::Distance) {
    c > a + b;
}

but it wouldn’t compile:

expected <T as Tr>::Distance, found <<T as Tr>::Distance as core::ops::Add>::Output

I’ve also tried:

type Distance: PartialOrd + Add<Output=Distance>;

but it wouldn’t compile either.

So I’ve ended up with:

pub trait Tr {
    type Distance: PartialOrd + Add<Output=<Self as Tr>::Distance>;
}

which I think is quite ugly. Could this syntax be simplified? e.g. by default assume that Add's Output=Self or at least allow type to be self-referential without going through <Self as Trait>?


#2

If we add the by-default assumption that would prevent not having it. We could potentially make a trait’s associated types available within its definition, through.


#3

Currently, you can simplify this slightly by using Self instead of <Self as Tr>.

pub trait Tr {
    type Distance: PartialOrd + Add<Output=Self::Distance>;
}