While I was reading this Reddit thread about the design trade-offs of Swift language generics (that also contains an awesome comment by Gankro): https://www.reddit.com/r/rust/comments/7gkiie/implementing_swift_generics_video/
I've seen the Reddit user jrmuizel express a common desire:
It would be nice if you could optionally compile rust code with this model to avoid having to monomorphize all the time and therefore improve build times.
This reminds me of a paper I've read few years ago, from 2009, Dan Tsafrir, Robert W. Wisniewski, David F. Bacon, and Bjarne Stroustrup: Minimizing Dependencies within Generic Classes for Faster and Smaller Programs. ACM OOPSLA'09:
I don't know how much generally applicable are the ideas of this paper, if they could be used to reduce the generics bloat in Rust code.
It explains the collections contain methods that depend only a subset of the template arguments:
the size method that returns the number of elements stored by the std::set
template<typename T, typename C, typename A> size type set<T,C,A>::size() const { return this->count; }
This method just returns an integer data member (the alias size type is some integer type) and so its implementation is independent of T, C, and A. Yet, for every T/C/A combination, the compiler emits another identical instantiation.
Then the paper suggests template hoisting and generalized template hoisting as possible solutions.
Later the paper proposed a language-level solution, that in Rust-y language could look like this:
struct C<X, Y, Z> {
x: X,
y: Y,
z: Z,
}
impl<X, Y, Z> C<X, Y, Z> {
// For backward compatibility, this is
// equivalent to: fn f2() use X,Y,Z
fn f1(self) {
}
// Only allowed to use X or Z, not Y
fn f2(&self) use X, Z {
}
}
The f2 method is not tied to the generic Y type.