Skip to content

Intrinsic for type_name_of_id to power a better impl Debug for TypeId? #61533

Open
@anp

Description

@anp
Member

Currently TypeIds have uninformative derived Debug impls:

fn main() {
    println!("{:?}", std::any::TypeId::of::<usize>());
}
   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 0.91s
     Running `target/debug/playground`
TypeId { t: 8766594652559642870 }

This results in fairly poor Debug output for dynamic types like anymap.

I think it could be quite nice for debugging/logging/etc to allow printing the type name from a TypeId in the Debug impl. It would provide an out of the box improvement to debugging existing dynamic typing tools, and IIUC the contents of Debug impls in the standard library are not considered stable so there's neither a breaking change here nor a de facto stabilization of the type_name representation.

I assume this would need to rely on some unstable intrinsic being exposed to get the type_name of an ID at run time, but I'm not really aware what would be needed.

Thoughts? cc @oli-obk as we had discussed this a bit on IRC.

Activity

czipperz

czipperz commented on Jun 5, 2019

@czipperz
Contributor

I think this is a cool idea. However, to implement this we would probably have to add some sort of type table to each application binary. That seems like it could become extremely expensive as each instantiation of a generic type would be stored separately.

oli-obk

oli-obk commented on Jun 5, 2019

@oli-obk
Contributor

The amount of extra memory needed is fairly limited, as most of these type names will already have ended up somewhere in the binary. So we could just have the other places refer to the table entries instad of having their own version of the name.

For release builds we could even just skip this table entirely and fall back to id printing.

Alternatively we can make the TypeId struct have a &'static str field in debug mode and just fill it in 😆

added
T-langRelevant to the language team
T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.
needs-fcpThis change is insta-stable, or significant enough to need a team FCP to proceed.
on Jun 5, 2019
Centril

Centril commented on Jun 5, 2019

@Centril
Contributor

Alternatively we can make the TypeId struct have a &'static str field in debug mode and just fill it in 😆

Ostensibly we need something like this to deal with the soundness hole in #10389?

oli-obk

oli-obk commented on Jun 5, 2019

@oli-obk
Contributor

oh, you mean the solution where each TypeId is in fact backed by a (non-deduplicateable and non-duplicatable) static item and the TypeId is just a pointer to that? And the value of that static could be the type's name (or a zero length string in the release-mode version).

anp

anp commented on Jun 5, 2019

@anp
MemberAuthor

Interesting ideas! If I had my druthers it would be feasible to use this in release mode as well, as I am interested in using the output for logging.

Centril

Centril commented on Jun 6, 2019

@Centril
Contributor

@oli-obk Something in that spirit yeah.

gnzlbg

gnzlbg commented on Jun 13, 2019

@gnzlbg
Contributor

I imagine this as follows.

We would have a:

trait TypeName {
    fn name(&self) -> &'static str;
}

that is implemented for all types:

impl<T: ?Sized> TypeName for T {
    #[cfg(rtti)]
    #[lang_item = "type_name_blanket_impl"]
    fn name(&self) -> &'static str;
    #[cfg(not(rtti))]
    fn name(&self) -> &'static str { "rtti-disabled" }
}

Then we would have a global compiler switch, e.g., -C rtti=on/off, that controls what the trait impls do. When -C rtti=on, TypeName::type_name implementations are magically generated to return the &'static str containing the name of the type are added for each type in the whole program. When -C rtti=on, only a blanket impl, e.g., returning "rtti-disabled", is provided.

eddyb

eddyb commented on Apr 9, 2022

@eddyb
Member

(cross-linking) TypeId containing a mangled name would allow this more efficiently (in terms of binary size) than via std::any::type_name, and is arguably necessary for sound TypeId (at least one some platforms?): #77125 (comment)

eddyb

eddyb commented on Apr 9, 2022

@eddyb
Member

Update: finally opened #95845 with a (v0) mangling-based TypeId representation (which could eventually be used to allow runtime demangling of type names from TypeId).

8 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-langRelevant to the language teamT-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.needs-fcpThis change is insta-stable, or significant enough to need a team FCP to proceed.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @eddyb@oli-obk@Centril@gnzlbg@anp

        Issue actions

          Intrinsic for `type_name_of_id` to power a better `impl Debug for TypeId`? · Issue #61533 · rust-lang/rust