# \[Pre-RFC\] TypeId for non-static Types

**URL:** <https://internals.rust-lang.org/t/pre-rfc-typeid-for-non-static-types/4467>\
**Category:** Uncategorized\
**Created:** [December 16, 2016, 10:12am UTC](https://internals.rust-lang.org/t/pre-rfc-typeid-for-non-static-types/4467 "2016-12-16T10:12:20Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![KodrAus](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kodraus/32/2816_2.png) [@KodrAus](https://internals.rust-lang.org/u/KodrAus)\
**Post date:** [December 16, 2016, 10:12am UTC](https://internals.rust-lang.org/t/pre-rfc-typeid-for-non-static-types/4467/1 "2016-12-16T10:12:20Z")

</div>

# Summary

Remove the `'static` bound from the `type_id` intrinsic so users can experiment with reflection over non-static types.

# Motivation

A common method for storing a map of arbitrary data is to use something like a `HashMap<TypeId, Box<Any>>`. The problem is that a `TypeId` can only be constructed for a static type. This is a reasonable constraint for the stable API, because lifetimes may need to play a part in equality checks by type id. However there are cases where a user is boxing trait objects to work around lifetimes, so they only need to guarantee that data stored with a particular key is of a particular type.

This can be worked around on Rust now by using a trait with an associated type that’s expected to be a `'static` version of the implementor:

```rust
unsafe trait Keyed {
	type Key: 'static;
}

struct NonStaticStruct<'a> {
	a: &'a str
}
unsafe impl <'a> Keyed for NonStaticStruct<'a> {
	type Key = NonStaticStruct<'static>;
}

```

The `Keyed` trait needs to be marked as `unsafe` because it could lead to undefined behaviour if implemented incorrectly and used for transmuting memory.

This RFC proposes simply removing the `'static` bound from the `type_id` intrinsic, leaving the stable `TypeId` and `Any` traits unchanged. That way users who opt-in to unstable intrinsics can build the type equality guarantees they need without waiting for stable API support.

This is an important first step in expanding the tools available to users at runtime to reason about their data. With the ability to fetch a unique `type_id` for non-static types, users can build out their own `TypeId` or `Any` traits.

# Detailed design

Remove the `'static` bound from the `type_id` intrinsic in `libcore`.

# How We Teach This

This changes an unstable compiler intrinsic so we don’t need to teach it.

# Drawbacks

# Alternatives

Create a new intrinsic that’s specifically designed never to take lifetime information into account. This intrinsic would behave exactly as `type_id` does now. Having a totally separate intrinsic means `type_id` could evolve without breaking existing expectations.

# Unresolved questions

---

<div class="post-metadata">

**Author:** ![bluss](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bluss/32/2264_2.png) [@bluss](https://internals.rust-lang.org/u/bluss)\
**Post date:** [December 16, 2016, 4:31pm UTC](https://internals.rust-lang.org/t/pre-rfc-typeid-for-non-static-types/4467/2 "2016-12-16T16:31:10Z")

</div>

I think at the least that the type\_id intrinsic should allow `T` without lifetime bound, so that we can prototype something out of tree.

---

<div class="post-metadata">

**Author:** ![KodrAus](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kodraus/32/2816_2.png) [@KodrAus](https://internals.rust-lang.org/u/KodrAus)\
**Post date:** [December 16, 2016, 10:31pm UTC](https://internals.rust-lang.org/t/pre-rfc-typeid-for-non-static-types/4467/3 "2016-12-16T22:31:48Z")

</div>

Do changes to intrinsics require an RFC?

---

<div class="post-metadata">

**Author:** ![KodrAus](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kodraus/32/2816_2.png) [@KodrAus](https://internals.rust-lang.org/u/KodrAus)\
**Post date:** [December 20, 2016, 8:48am UTC](https://internals.rust-lang.org/t/pre-rfc-typeid-for-non-static-types/4467/4 "2016-12-20T08:48:55Z")

</div>

I’ve decided to just turn this topic into a Pre-RFC for removing the `'static` bound from `type_id`. I’m not sure how much detail this particular request needs.

---

<div class="post-metadata">

**Author:** ![nikomatsakis](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nikomatsakis/32/5410_2.png) [@nikomatsakis](https://internals.rust-lang.org/u/nikomatsakis)\
**Post date:** [December 22, 2016, 4:08pm UTC](https://internals.rust-lang.org/t/pre-rfc-typeid-for-non-static-types/4467/5 "2016-12-22T16:08:00Z")

</div>

Hmm. I’m not 100% opposed to this. It is certainly subtle that values with two distinct types can nonetheless have an equal `TypeId`. I wonder if there is an alternative name we could give that would make this clearer. OTOH, it’s subtle, but we can certainly document it.

---

<div class="post-metadata">

**Author:** ![KodrAus](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kodraus/32/2816_2.png) [@KodrAus](https://internals.rust-lang.org/u/KodrAus)\
**Post date:** [December 28, 2016, 4:06am UTC](https://internals.rust-lang.org/t/pre-rfc-typeid-for-non-static-types/4467/6 "2016-12-28T04:06:32Z")

</div>

Correct me if I’m wrong, but right now the `TypeId` assumes a type with ‘no’ lifetimes is equivalent to a type with only `'static` lifetimes, because lifetimes aren’t available to the intrinsic right now. This assumption isn’t exposed directly because of the `'static` bound, but is still there because maintaining backwards compatibility would mean keeping `TypeId`s that exist right now the same.

I can’t think of a concrete usecase for reflecting over lifetimes at runtime though, so I’m not sure if assigning the same `TypeId` to `Struct<'static>` and `Struct<'_>` is the right call or not.

We could solve this on the intrinsic with documentation and when it comes time to add lifetime support to `TypeId` the problem can be solved there based on the motivations of the RFC.

---

<div class="post-metadata">

**Author:** ![mitsuhiko](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mitsuhiko/32/379_2.png) [@mitsuhiko](https://internals.rust-lang.org/u/mitsuhiko)\
**Post date:** [March 2, 2018, 12:46pm UTC](https://internals.rust-lang.org/t/pre-rfc-typeid-for-non-static-types/4467/7 "2018-03-02T12:46:28Z")

</div>

I just came across this again. Has there been a discussion about introducing a `RuntimeTypeId` as an alias that comes without the static restriction?

---

<div class="post-metadata">

**Author:** ![KodrAus](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kodraus/32/2816_2.png) [@KodrAus](https://internals.rust-lang.org/u/KodrAus)\
**Post date:** [March 3, 2018, 9:15am UTC](https://internals.rust-lang.org/t/pre-rfc-typeid-for-non-static-types/4467/8 "2018-03-03T09:15:08Z")

</div>

There’s an [accepted RFC](https://github.com/rust-lang/rfcs/blob/master/text/1849-non-static-type-id.md) for removing the restriction on the `type_id` intrinsic that could be used to build a `RuntimeTypeId`, but I think it’s run into issues in implementation.

---

<div class="post-metadata">

**Author:** ![KodrAus](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kodraus/32/2816_2.png) [@KodrAus](https://internals.rust-lang.org/u/KodrAus)\
**Post date:** [March 25, 2019, 8:27am UTC](https://internals.rust-lang.org/t/pre-rfc-typeid-for-non-static-types/4467/9 "2019-03-25T08:27:29Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
