Search code examples
rustinlinecompile-time-constant

const fn vs inline attribute


In the following example, I believe that when the function Struct::new is called, its body will be inlined (copied) to the call-site because of the #[inline] attribute. This will result in more code being generated and slower compile times but better runtime performance because of the eliminated function call.

impl Struct {
    #[inline]
    pub fn new() -> Self {
        // initialization code
    }
} 

Nowadays const fn are stable on Rust. When someone declares a function as const, it should allow the compiler to evaluate it at compile time.

impl Struct {
    pub const fn new() -> Self {
        // initialization code
    }
} 

Does declaring the function as const and omitting the #[inline] attribute offer the same trade-offs as the code in the previous example (because the function is evaluated in compile-time and its result is "inlined" to the call-site)? Should we replace all the #[inline] attributes with const? If they are not same, what are the differences?


Solution

  • #[inline] and const are completely different things and the one is not a superset of the other:

    • #[inline] guides the compiler to not make a heuristic decision whether or not to inline the function body into the caller. The compiler is still free to disregard this attribute entirely or at specific call-sites if it so chooses for whatever reason since inlining does not change the program's behaviour in any observable way.
    • const is part of the function's signature and guarantees that the function can be (but not necessarily is) evaluated at compile time. The compiler may choose to evaluate the function body at compile time if it can, yet it is free to move that to runtime. The reason to make a function const is that the possibility to be evaluated in a const-context is part of the function's signature, guaranteeing this property in a semver-stable way. That is, a function that can be called in a const-context should not suddenly lose this property without a semver-bump.

    The above is the reason why const is part of the publicly documented function signature but #[inline] is not.

    So no, do not blindly exchange #[inline] for const.