Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracking issue for type_id stabilization #27745

Closed
aturon opened this issue Aug 12, 2015 · 42 comments · Fixed by #57834
Closed

Tracking issue for type_id stabilization #27745

aturon opened this issue Aug 12, 2015 · 42 comments · Fixed by #57834
Labels
B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@aturon
Copy link
Member

aturon commented Aug 12, 2015

The method get_type_id in Any is intended to support reflection. It's currently unstable in favor of using an associated constant instead.

@aturon aturon added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. B-unstable Blocker: Implemented in the nightly compiler and unstable. labels Aug 12, 2015
@bluss
Copy link
Member

bluss commented Sep 8, 2015

It was pointed out it's one of the very few methods to be named with get_ prefix, so it could be renamed to just type_id().

@aturon
Copy link
Member Author

aturon commented Sep 8, 2015

I suspect this is just some very old convention that wasn't updated during stabilization (since we didn't stabilize this API).

@flosse
Copy link

flosse commented Jul 25, 2016

Any progress here?

@UserAB1236872
Copy link

I tried to tackle it, but it looks like the main problem is that TypeId::of isn't constant and can't be constant. It calls intrinsics::type_id which, on any attempt to make it a const function yields the cryptic error "unmatched visibility pub". This would be a simple change if TypeId::of 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).

@alexcrichton
Copy link
Member

Removing nomination as this was an accidental mistake about what this issue was about.

@fschutt
Copy link
Contributor

fschutt commented Mar 17, 2017

Any update on this? Is is discouraged to use it in current code?

@jweinst1
Copy link

jweinst1 commented Apr 9, 2017

Is there any other way to do reflection or dynamic typing that will work?

@SimonSapin
Copy link
Contributor

@jweinst1 the rest of the std::any::Any trait is stable:

fn is<T>(&self) -> bool where T: Any;
fn downcast_ref<T>(&self) -> Option<&T> where T: Any;
fn downcast_mut<T>(&mut self) -> Option<&mut T> where T: Any;
fn downcast<T>(Box<self>) -> Result<Box<T>, Box<Any>> where T: Any ;

In each of these the call site is specifying a specific T. (Internally the implementations of these method compare Self::type_id() and T::type_id().)

@SimonSapin
Copy link
Contributor

I’ve just realized that TypeId and TypeId::of are also stable, so you could copy the Any trait into your own code.

@Mark-Simulacrum Mark-Simulacrum added the C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. label Jul 22, 2017
@Mark-Simulacrum
Copy link
Member

I propose we make TypeId::of a constant function. This should be a rather trivial step, primarily just adding it to the list of constant intrinsics as far as I can tell. (@eddyb Can you confirm?).

Once that's done, we can add a constant to Any and Error that'll replace the currently unstable methods associated with both, and stabilize those.


@SimonSapin I don't think it's that easy since there exist methods in the wild that pass around trait objects (&Any and &Error) 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.

@sfackler
Copy link
Member

It might be better off as an associated constant if possible.

@Mark-Simulacrum
Copy link
Member

I might not be understanding, but I think that's what I suggested? That we have something like const TYPE_ID: TypeId = TypeId::of::<Self>(); in Any and Error?

@sfackler
Copy link
Member

Oh right derp, there isn't anywhere to put the constant on TypeId itself since it isn't parameterized.

@Badel2
Copy link
Contributor

Badel2 commented Jan 30, 2018

Alright, I'm working on this and I think I managed to turn type_id into a constant intrinsic, meaning I can do const A: TypeId = TypeId::of::<T>();, however when I try to add it to the Any 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 impl Any block, not in trait Any. This can be done after the next stage0.

@glaebhoerl
Copy link
Contributor

I wonder if #10389 is relevant here

kennytm added a commit to kennytm/rust that referenced this issue Feb 4, 2018
Turn `type_id` into a constant intrinsic

rust-lang#27745

The method `get_type_id` in `Any` is intended to support reflection. It's currently unstable in favor of using an associated constant instead. This PR makes the `type_id` intrinsic a constant intrinsic, the same as `size_of` and `align_of`, allowing `TypeId::of` to be a `const fn`, which will allow using an associated constant in `Any`.
@Badel2
Copy link
Contributor

Badel2 commented Mar 3, 2018

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:

trait Any {
    const TYPE_ID: TypeId = TypeId::of::<Self>();
}

And this also won't work, because it just stores the TypeId of the Any trait object, not the TypeId of the type that implements Any:

trait Any {}
impl Any {
    const TYPE_ID: TypeId = TypeId::of::<Self>();
}

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 TypeId.

@SimonSapin
Copy link
Contributor

SimonSapin commented Mar 16, 2018

we need to add support for associated constants in trait objects

I think this wouldn’t work? This code:

fn foo(object: &Any) {
    let type_id = object.get_type_id();
}

… can call a trait method from a trait object. Accessing an associated constant would be <T as Any>::TYPE_ID, but this code does not know what T is.

Other code that does have a concrete T type can use TypeId::of::<T>(), which is now a const fn.

So I propose keeping this method as a method, renaming to type_id to remove the get_ prefix, and stabilizing.

@sfackler
Copy link
Member

That seems reasonable.

@SimonSapin
Copy link
Contributor

I propose keeping this method as a method, renaming to type_id to remove the get_ prefix, and stabilizing.

@rfcbot fcp merge

@rfcbot rfcbot added the proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. label Mar 17, 2018
@rfcbot
Copy link

rfcbot commented Mar 17, 2018

Team member @SimonSapin has proposed to merge this. The next step is review by the rest of the tagged teams:

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 this document for info about what commands tagged team members can give me.

@sfackler
Copy link
Member

Seems like we might as well make it a const method while we're stabilizing it. It should be pretty trivial since TypeId::of is already const.

@leoyvens
Copy link
Contributor

We want to revisit trait objects in general soon after the 2018 edition stuff is done.

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.

@rfcbot
Copy link

rfcbot commented Mar 28, 2018

The final comment period is now complete.

tmccombs added a commit to tmccombs/rust that referenced this issue Apr 3, 2018
@tmccombs
Copy link
Contributor

tmccombs commented Apr 3, 2018

I figured we'd hold off on stabilizing this as it requires some form of rustc storing constants in vtables (which is currently unimplemented).

Are there any plans to implement this, or RFCs that specify that?

@Diggsey
Copy link
Contributor

Diggsey commented Apr 6, 2018

@withoutboats

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 get_type_id in that trait anyway (see the mopa crate for example).

That's the exact motivation for stabilising this: as a trait method it is directly callable on trait objects extending Any. That means that mopa and the like can get rid of their custom Any traits, which I view as a significant benefit.

This issue is even directly linked from comments in the mopa source code: https://github.com/chris-morgan/mopa/blob/master/src/lib.rs#L163

We should stabilize this as-is - I don't see how performance is a concern since we already have TypeId::of 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.

@Centril Centril added disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. and removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels May 24, 2018
@tmccombs
Copy link
Contributor

tmccombs commented Jun 3, 2018

Unfortunately I think there may be a bug in fcp where I registered a blocking concern to block stabilizing this method but it didn't halt the FCP process.

From #49613 (comment)

@Centril should this have the finished-final-comment-period label?

See also, #27745 (comment)

@Centril
Copy link
Contributor

Centril commented Jun 3, 2018

@tmccombs unclear; I defer to @rust-lang/libs

@TimDiekmann
Copy link
Member

How likely is this to be stabilized? Will the _get prefix be removed?

@SimonSapin
Copy link
Contributor

Very, since FCP to stabilize is done. Yes, since that’s was part of the FCP proposal.

Stabilization PR: #57834

Centril added a commit to Centril/rust that referenced this issue Jan 23, 2019
@bors bors closed this as completed in 5749bac Jan 24, 2019
@TimDiekmann
Copy link
Member

Thank you @SimonSapin. I wasn't sure since the FCP was months ago.

@SimonSapin
Copy link
Contributor

Yeah, sometimes we just forget to follow up. Pinging open issues like you did can help, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.