Can rust limit the monomorphisation of a function?

I have a generic function over T, but the only time T is used is when getting the size:

fn alloc_n<T>(&self, n: usize) {
    let size = n * size_of::<T>();
    ... some more code ...
}

Does rust (or llvm) reduce the surface area of the monomorphisation to only the size_of::<T>()?

Put another way, would it generate a new alloc_n for every T being called upon, or reduce it to just generating new size_ofs?

1 Like

No and that's why you may find a trick in std where “outer” generic function does something with T and then calls nested function that does an actual work.

But that have to be handled by programmer, currently.

It would generate new alloc_n, sure. Linker would then merge bodies of functions with the exact same size_of, but nothing would merge bodies for different size_of.

1 Like

It would generate different alloc_n functions. The optimization you have in mind is called polymorphization and rustc used to support it as an unstable optimization, but it was removed (I think because it was buggy/broken).

A usual manual optimization that is done in these cases is to move the body of alloc_n to a separate function that doesn't depend on T and pass it the value of size_of::<T>() as a parameter.

Note that in Rust. unlike C++, things that are in generic (const, static, or fn) and not monomorphised. That's why it's common to have that second function inside: it's guaranteed to be unaccessible to any other function and yet it's not monomorphised.

It could still be inlined, of course.

Nit: what you call "things" are more formally called items.

2 Likes

This is particularly common for AsRef, for example

1 Like