Suppose we have the following implementation:
trait S<T> {
type Item;
}
impl<T> S<T> for Mutex<T> {
type Item = T;
}
struct MyStruct<T1: S<u8>, T2: S<i32>, T3: S<f64>> {
feild1: T1,
feild2: T2,
feild3: T3,
}
let a: MyStruct<Mutex<u8>, Mutex<i32>, Mutex<f64>> = MyStruct {
feild1: Mutex::new(1),
feild2: Mutex::new(5),
feild3: Mutex::new(9.),
};
Each field in MyStruct
implements S
, but we need to use a separate generic parameter for each of them. This can lead to an explosion of generic parameters in your project.
If we can simplify this writing to the following:
struct MyStruct<T: S<_>> {
feild1: T<u8>,
feild2: T<i32>,
feild3: T<f64>,
}
We can just use S<_>
in the generic declaration, and let the struct itself decide which generic type to use inside S
.
I'm not sure if this language feature has anything to do with GAT or HKT (higner-kinded type), but since it has alternative implementations (i.e. the generic explosion case above), I think it can be implemented.
The motivation of this is parallel rustc. I've done quite a bit of work and research on parallel rustc. Yesterday I tried refactoring the Lock
data structure to try to make the nightly compiler parallelize (PR here), but the performance hit is still huge.
If we had the language features mentioned above, we could do this by implementing the S
trait for both RefCell
and Mutex
, and then specifying whether T
was a RefCell
or Mutex
in the struct declaration, so that It is possible to have both shared and non-shared instances of MyStruct
. Based on this we can ship parallel compilation without degrading performance.