Change:
The method in is intended to support reflection. It's currently unstable in favor of using an associated constant instead.
It was pointed out it's one of the very few methods to be named with prefix, so it could be renamed to just .
I suspect this is just some very old convention that wasn't updated during stabilization (since we didn't stabilize this API).
Any progress here?
I tried to tackle it, but it looks like the main problem is that isn't constant and can't be constant. It calls which, on any attempt to make it a const function yields the cryptic error "unmatched visibility pub". This would be a simple change if was a const fn. (Though making an extern function const is probably dicey from a compiler perspective anyway, I'm not an expert on that).
Removing nomination as this was an accidental mistake about what this issue was about.
Any update on this? Is is discouraged to use it in current code?
Is there any other way to do reflection or dynamic typing that will work?
the rest of the trait is stable: In each of these the call site is specifying a specific . (Internally the implementations of these method compare and .)
I’ve just realized that and are also stable, so you could copy the trait into your own code.
I propose we make a constant function. This should be a rather trivial step, primarily just adding it to the as far as I can tell. ( Can you confirm?). Once that's done, we can add a constant to and that'll replace the currently unstable methods associated with both, and stabilize those. I don't think it's that easy since there exist methods in the wild that pass around trait objects ( and ) and since we don't have trait object casts today (if we ever will, not sure if it's possible, seems like perhaps not) without these constants/methods there's not a way to retrieve the underlying type of a trait object.
It might be better off as an associated constant if possible.
I might not be understanding, but I think that's what I suggested? That we have something like in and ?
Oh right derp, there isn't anywhere to put the constant on TypeId itself since it isn't parameterized.
Alright, I'm working on this and I think I managed to turn into a constant intrinsic, meaning I can do , however when I try to add it to the trait I get an error (E0038) that says "the trait cannot contain associated consts". Anyway, I'll add a test and submit a PR. Edit: I solved the mistery, the const needs to be inserted in the block, not in . This can be done after the next stage0.
I wonder if is relevant here
It turns out that associated constants cannot be used in trait objects, because the constants aren't stored in the vtable. So this won't work: And this also won't work, because it just stores the of the trait object, not the of the type that implements : So assuming we still want to make TYPE_ID an associated constant, we need to add support for associated constants in trait objects, or make this a special case and add a dedicated field to the vtable which stores the .
I think this wouldn’t work? This code: … can call a trait method from a trait object. Accessing an associated constant would be , but this code does not know what is. Other code that does have a concrete type can use , which is now a . So I propose keeping this method as a method, renaming to to remove the prefix, and stabilizing.
That seems reasonable.
fcp merge
Team member has proposed to merge this. The next step is review by the rest of the tagged teams: [x] [x] [ ] [ ] [x] [x] [x] No concerns currently listed. Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See for info about what commands tagged team members can give me.
Seems like we might as well make it a const method while we're stabilizing it. It should be pretty trivial since is already const.
:bell: This is now entering its final comment period, as per the . :bell:
cannot be const because it is a trait method:
concern performance Are we sure we want to stabilize this as a function? I figured we'd hold off on stabilizing this as it requires some form of rustc storing constants in vtables (which is currently unimplemented). As a result the proposed can have not-so-great perf as it's a virtual function call rather than a simple load. Do we have good rationale for stabilizing the known slower approach? Are there use cases today that are critically waiting on to stabilize to get enabled?
I don’t mind waiting for another solution, but in addition to implementing support for constants in vtables we’d need syntax to access them. As far as I know no such syntax exists today, and I don’t know have a clear idea of what it could look like.
Yes it's true that it's quite aways away, but is the rationale for stabilizing these today with known drawbacks?
It doesn’t have to be today, but having a realistic path to some resolution one way or another within the next few months would be nice. This issue is two and a half years old. This method has been unstable for as long as the stability mechanism has existed. In my opinion features being unstable should be a temporary state while we figure out unresolved questions (and ideally get some usage experience). At some point we should decide: if this feature turns out not to be useful, let’s deprecate and later remove it. If it is useful, then there is a need that we’re failing to serve if after several years we’re still waiting for an hypothetical language feature when we don’t even have a sketch of what that would look like. Our choice for the foreseeable future is not slower vs faster, it’s slower vs nothing. If we stabilize, we always have the option to deprecate later when/if something better comes along.
I have a way out, I think: keep as unstable; introduce an inherent method on calling ; change to use vtable constants whenever those are introduced into the language. Edit: s/typeof/typeid/
I agree that we shouldn't leave issues in limbo forever, but I don't think it sounds like it's urgent we do anything on this in the near future? We have a theoretical path to stabilization and if necessary to stabilize in the near future we can do so with the understanding that it's not as good as it may be one day and plan appropriately. To that end I'd still like to see an argument in favor of stabilizing this today. I think it's fine to do so, but it'd be best to have a reason more than "this has been unstable for quite some time". Lots of implementation details in the standard library are pema-unstable, and this is currently an implementation detail of the method.
I'm not certain that there's a benefit to stabilizing this. If I want to create a downcastable trait object, I have to define my own in that trait anyway (see the crate for example). But I think any better solution would not benefit from this being unstable either. Probably, a better solution would involve deprecating the trait entirely, since it works so poorly for this feature (again, see ). We'd want to extend the language support beyond the type-id intrinsic probably, to include something like the ability to get the type id from any trait object's vtable, or the ability to downcast any trait object with first class syntax, or something along those lines. We want to revisit trait objects in general soon after the 2018 edition stuff is done.
It’s fine that those implementation details exist, but we should be clear about what items are in that category as opposed to features that are not stable yet but have some path to stabilization. Perma-unstable implementation details have and no tracking issue. The existence of this open tracking issue indicates that there is something to be tracked. Closing it and deciding that should be a hidden implementation detail is one possible resolution.
Hm? Did rfcbot not register the concern here? I thought it normally edits those into its post.
Unfortunate timing, considering a new syntax will be introduced for them. This would otherwise be a good opportunity to introduce small breaking changes to behavior. But I guess that's off topic here.
The final comment period is now complete.
Are there any plans to implement this, or RFCs that specify that?
That's the exact motivation for stabilising this: as a trait method it is directly callable on trait objects extending . That means that and the like can get rid of their custom traits, which I view as a significant benefit. This issue is even directly linked from comments in the source code: We should stabilize this as-is - I don't see how performance is a concern since we already have for the static case, and we're still leaving open the possibility of adding it as an associated constant if trait objects gain support for them.
From should this have the label? See also,
unclear; I defer to
How likely is this to be stabilized? Will the prefix be removed?
Very, since FCP to stabilize is done. Yes, since that’s was part of the FCP proposal. Stabilization PR:
Thank you I wasn't sure since the FCP was months ago.
Yeah, sometimes we just forget to follow up. Pinging open issues like you did can help, thanks!

Discussion:
/// # Examples /// /// ``` <del> /// #![feature(get_type_id)] /// </del> /// use std::any::{Any, TypeId}; /// /// fn is_string(s: &dyn Any) -> bool { <del> ///     TypeId::of::<String>() == s.get_type_id() </del> <ins> ///     TypeId::of::<String>() == s.type_id() </ins> /// } /// /// fn main() {

///     assert_eq!(is_string(&"cookie monster".to_string()), true); /// } /// ``` <del> #[unstable(feature = "get_type_id", reason = "this method will likely be replaced by an associated static", issue = "27745")] fn get_type_id(&self) -> TypeId; </del> <ins> #[stable(feature = "get_type_id", since = "1.34.0")] fn type_id(&self) -> TypeId; </ins> } #[stable(feature = "rust1", since = "1.0.0")] impl<T: 'static + ?Sized > Any for T { <del> fn get_type_id(&self) -> TypeId { TypeId::of::<T>() } </del> <ins> fn type_id(&self) -> TypeId { TypeId::of::<T>() } </ins> } ///////////////////////////////////////////////////////////////////////////////

let t = TypeId::of::<T>(); // Get TypeId of the type in the trait object <del> let boxed = self.get_type_id(); </del> <ins> let concrete = self.type_id(); </ins> // Compare both TypeIds on equality <del> t == boxed </del> <ins> t == concrete </ins> } /// Returns some reference to the boxed value if it is of type `T`, or

// compile-pass <del> #![feature(get_type_id)] </del> #![allow(dead_code)] mod foo { pub use self::bar::T;

fn f() { let error = ::std::thread::spawn(|| {}).join().unwrap_err(); <del> error.get_type_id(); // Regression test for #21670 </del> <ins> error.type_id(); // Regression test for #21670 </ins> }