#[inline(always)]suggests that an inline expansion should always be performed.
#[inline(never)]suggests that an inline expansion should never be performed.
Note: #[inline] in every form is a hint, with no requirements on the language to place a copy of the attributed function in the caller.
However, I don't want to "suggest" that my function not be inlined, I want to force the compiler to not inline it. Is there a way I can do this in Rust?
Unless you're willing to implement your own back end (like LLVM), this is impossible. #[inline(never)] is as close as you're going to get, as only laughably simple cases get inlined.
If you're doing this for the purpose of messing with the assembly code at runtime, simply include an inline assembly block with an exported label. Rust specifically forbids the compiler from assuming that the contents of an inline assembly block are the instructions that will actually be executed, and can only check stuff declared in the options (except that the linker can observe its actual size in bytes).
Oops, sorry, the above is wrong:
You cannot assume that an asm! block will appear exactly once in the output binary. The compiler is allowed to instantiate multiple copies of the asm! block, for example when the function containing it is inlined in multiple places.
While the code inside the function is running, I want tools that profile the function based on stack frames to be able to see a stack frame corresponding to this function (which goes away if the function is inlined).
I want to be able to inspect the binary and find the assembly code for the function as a function, which isn't guaranteed to still exist in the final binary if the function is inlined (yes, it could be optimized out entirely if the optimizer shows it isn't needed, but I'm fine with that risk).
Note that LLVM still const propagates arguments even into #[inline(never)] functions afaik. And it propagates inferred attributes like pure outwards which may allow the call to be removed entirely.