Skip to content

Feature request: Use 'trampolines' to make most of the body of a generic function non-generic #77960

Open
@jyn514

Description

@jyn514

A common pattern in Rust, especially in the standard library, is to have two versions of a function: one generic and one with the actual implementation. For example, Error::new() immediately delegates to a non-generic function _new():

#[stable(feature = "rust1", since = "1.0.0")]
pub fn new<E>(kind: ErrorKind, error: E) -> Error
where
E: Into<Box<dyn error::Error + Send + Sync>>,
{
Self::_new(kind, error.into())
}
fn _new(kind: ErrorKind, error: Box<dyn error::Error + Send + Sync>) -> Error {
Error { repr: Repr::Custom(Box::new(Custom { kind, error })) }
}

This benefits both compile- and run-time: compiletime because LLVM has to do less work compiling the large implementation of the function body many times, and runtime because generic version can safely be marked as #[inline] without bloating the instruction cache.

However, most libraries do not do this, for the simple reason that it's tedious and annoying to do (and you have to already know about it). It would be amazing if rustc could do this transformation itself. I expect this would help greatly with #65031, as well as compile times across the ecosystem.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-codegenArea: Code generationA-mir-optArea: MIR optimizationsA-monomorphizationArea: MonomorphizationC-feature-requestCategory: A feature request, i.e: not implemented / a PR.E-hardCall for participation: Hard difficulty. Experience needed to fix: A lot.I-compiletimeIssue: Problems and improvements with respect to compile times.I-heavyIssue: Problems and improvements with respect to binary size of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions