A common pattern in Rust, especially in the standard library, is to have two versions of a function: one generic and one with the actual implementation. For example, Error::new() immediately delegates to a non-generic function _new():
https://github.com/rust-lang/rust/blob/5565241f65cf402c3dbcb55dd492f172c473d4ce/library/std/src/io/error.rs#L250-L260
This benefits both compile- and run-time: compiletime because LLVM has to do less work compiling the large implementation of the function body many times, and runtime because generic version can safely be marked as #[inline] without bloating the instruction cache.
However, most libraries do not do this, for the simple reason that it's tedious and annoying to do (and you have to already know about it). It would be amazing if rustc could do this transformation itself. I expect this would help greatly with https://github.com/rust-lang/rust/issues/65031, as well as compile times across the ecosystem.
Thanks to @matklad for bringing this up in https://matklad.github.io/2020/10/15/study-of-std-io-error.html !
@llogiq wrote a library to perform this translation with a function attribute, momo. It works with a small number of traits (Into, AsRef and AsMut). Having rustc first optimize those three traits would be a good first step before working with arbitrary traits.
In the far future, I wish that rustc were able to automatically transform generics into code that uses trait objects, whenever applicable (the opposite of the "devirtualization" optimization).
This is a specific case of "outlining", and while outlining would help various things in a lot of places, its probably better to handle this specifically.
Most helpful comment
@llogiq wrote a library to perform this translation with a function attribute, momo. It works with a small number of traits (
Into,AsRefandAsMut). Having rustc first optimize those three traits would be a good first step before working with arbitrary traits.In the far future, I wish that rustc were able to automatically transform generics into code that uses trait objects, whenever applicable (the opposite of the "devirtualization" optimization).