I use "flattened" trait objects discussed in this thread. Unfortunately, it results in sub-optimal assembly as can be seen here: Compiler Explorer
Instead of pointing to original functions (lines 17 and 21), in the flattening function compiler creates call_once
wrappers which immediately jump to the original functions (it can be done because wrappers and the original functions have exactly the same ABI). Yes, it's a very minor overhead, but still an unpleasant one. Is there a reason why compiler can not collapse those wrappers? Or is it simple a missed optimization opportunity?
I could work around it by using #[inline(always)]
on Bar::foo1
and Bar::foo2
, but it's not always desirable to force inlining (e.g. if the Foo
trait used directly). Also it will make a bit harder to analyze such code in debugger. An alternative solution could be to transmute
function pointers as discussed in the linked thread, but I am not confident about soundness of such approach.
cc @SkiFire13