Skip to content

Generic inline functions are not always inline if generics are shared #103499

Closed
@jachris

Description

@jachris

Consider the following example.

// crate A
#[inline]
pub fn identity_i32(x: i32) -> i32 {
    x
}

#[inline]
pub fn identity<T>(x: T) -> T {
    x
}

pub fn use_from_a() {
    identity(42);
}
// crate B
fn main() {
    let _ = a::identity(42);
    let _ = a::identity_i32(42);
}

Current behavior

identity::<i32> is codegened only once, in crate A. The LLVM IR of crate B does not have the definition, only a declaration (because it was already instantiated for A). On the other hand, identity_i32 is codegened twice and thus available for LLVM inlining.

Expected behavior

I would have expected that crate A gets its own copy of identity::<i32>. This would match the behavior of non-generic inline functions, and it would also enable more optimizations.


Related: rust-lang/rust-clippy#2253 (the proposed change would make it meaningful to annotate generic functions with #[inline])

I would try to create a PR for this if we can agree that the expected behavior is more reasonable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions