Not sure if this should be language design or compiler, but it would be incredibly useful if we could also place inline attributes at the call site, and taking precedence over inline attributes at the function signature/declaration, i.e:
#[inline(always]
fn some_function() {
1
}
// Don't inline
#[inline(never)]
let result = some_function();
// inline
let result = some_function();
or any combination thereof.
just often i'll have multiple entry paths into a function, some cases I want it inline here, might be because the path to this point is call in a hot loop, but then at other parts i don't want it inline either due to code bloat, or the optimizer can actually optimize it better when it is not inline.
i've tried getting around this using macros, but that can get messy real quick.
Not that it's a real solution, but does calling an always-inline function via std::hint::black_box work to suppress inlining with any kind of reliability?
I'm pretty sure overloading is not something Rust is ever going to do. With the way type deduction works, you really want to have a single thing a name finds (though maybe trait lookup can interfere?).
black_box(function(argument)) optimises the call to the function with the specific argument and just discards assumptions about its result;
function(black_box(argument)) inlines the function call but doesn't substitute a known argument into the call; and
black_box(function)(argument) is equivalent to just function(argument) because black_box is generic over its return type and so you are giving it a function item type as its generic parameter; this means that there's only one possible return value (because there is only one possible value for each function item type), so the compiler still knows that it was function that was called.
You can cast the function to a function pointer and black-box that, e.g. black_box(function as fn(i32) -> i32)(argument) and that does reliably prevent the function being inlined. However, it also prevents the compiler seeing what the function's address is, so it has to generate code to call a function at an unknown address, which is slower than calling functions normally (potentially much slower if compiled for an environment which needs mitigations against speculative execution vulnerabilities).
I would have recommended the alternative of writing an #[inline(never)] wrapper around the function you wanted to outline, rather than using black_box. Annoyingly, though, in a simple test the wrapper ended up getting inlined anyway:
I misread the source code. It was constant propagation and I don't think it is a bug to propagate through inline(never) functions. If you have inputs it works.
Technically the inline attribute is always a hint, so I don't think this is a bug. You can open an issue like this one, but I'm guessing this is expected and allowed behavior.
For a body like num * 2 that's strictly always better to inline, no exceptions, I wouldn't say it's a bug. Try it with a realistic body then maybe it might be a bug, but also in some sense suboptimal optimization is never a "bug" in the strict since, because no optimizer is ever fully optimal.