Clone derived implementation opt out inline attribute

I've met a case that some large clone implementation is marked with inline attribute, which caused the code instantiated in several sub crates, which caused code bloated.
Is it a good idea to add a param for Clone derived macro to opt out inline? (I understand that I can implement Clone manually, it is not convenient.)

#[inline] allows the call to be inlined across the crate boundary, not enforce it. The compiler inline it only if it thinks it will improve performance. If you want smaller binary at the cost of runtime performance, use opt-level = "s".

1 Like

I understand that opt-level flags can produce smaller binary (with or without cost of runtime performance).
This is not the same thing, when a function marked with inline attribute, it's code will be "duplicated" to the client codegen unit (I guess?) to allow inline optimization, if inline not kicked in, the function will be stay at the client crate which is a new fn for llvm, which we have to pray for lto to optimize it out, but that may or may not happen. I think?

It's not "will be", it's "can be". It's #[inline(always)] which enforce the inlininng without caring performance.

I get the information from Monomorphization - Guide to Rustc Development, Non-generic #[inline] function, Crate A function appears with in a single CGU of Crate B, and exists even after post-inlining stage.

It means the crate B can read the body of #[inline]ed function from its dependency crate A so it can inline it if desired. It doesn't means the inlininng always happens.

That is what I trying to say, if inline not happens, then the crate A's fn is a new fn in crateB, if crateA also used by crateC, there will be two copy of fn.

If you mean the copies are included to the final executable binary, no that's not the case. The "copy" is not included to the build output as the compiler knows that the original crate which has this function already contains the code.

1 Like

yes, that is what I mean, are you sure it is not included to the build output? That is not what I observed.

How did you observed that non-inlined #[inline] functions are duplicated?

Use ddbug tool, observed there are several copies with same symbol name, located in different units.

EDIT: add ddbug link

Are you sure it's "same symbol name" and not "same demangled symbol name" (e.g. the generic function generated twice)?

yea, I'm sure, same symbol, demangled symbol stripped the crate name where instantiation happened. So I compare with mangled name.

Issue opened, Inline attribute caused multiple function generated in final output · Issue #94795 · rust-lang/rust · GitHub.