Skip to content

Mark TypeId::of as inline to avoid monomorphizing unnecessary code  #74362

Closed
@alecmocatta

Description

@alecmocatta

TypeId can be used to specialize code by comparing types explicitly (TypeId::of::<u8>() == TypeId::of::<T>(), examples in the wild) or implicitly (<dyn Any>::downcast_mut).

In release mode this works well; in debug mode though the unused impl is unnecessarily monomorphized and codegened, slowing compile time as well as run time.

It isn't a major issue as it only affects debug mode, but I wondered if it was worth marking TypeId::of, <TypeId as PartialEq>::eq, <dyn Any>::is and the various downcast methods as inline(always) to potentially reduce compile times and provide a nice debug mode runtime boost?

use std::any::{Any, TypeId};

struct Container<T>(T);

impl<T: 'static> Container<T> {
    fn foo(&mut self) {
        if let Some(_) = <dyn Any>::downcast_mut::<Container<u8>>(self) {
            // specialized impl
            std::process::abort();
        }
        // general impl
    }
    fn bar(&mut self) {
        if TypeId::of::<u8>() == TypeId::of::<T>() {
            // specialized impl
            std::process::abort();
        }
        // general impl
    }
}

fn main() {
    let mut c = Container(String::new());
    c.foo();
    c.bar();
}

See e.g. abort is present in IR/assembly: Playground

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-enhancementCategory: An issue proposing an enhancement or a PR with one.I-slowIssue: Problems and improvements with respect to performance of generated code.T-libsRelevant to the library 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