I had what is either a good or bad idea this morning, and I honestly can't decide which this is. I'd appreciate feedback on the idea.
TypeId is currently an opaque type that is (again, currently) just a wrapper around a
u64. The value of the TypeId for a given type can change between compiler versions. This means that if you want two chunks of code to communicate a TypeId between each other, you first need to make certain that they were both compiled with the same version of the compiler. While this is possible, it means that TypeIds are less useful for things like serialization1 or interoperability between languages. There are probably other places where stable values for TypeIds would be useful.
This is where my idea comes in. The IANA maintains a type tag registry for CBOR, with tag values all fitting within what a
u64 can hold. I'd like it if the
TypeId values for types that map directly to anything that is currently in the registry be set to those tag values.
For everything that doesn't match something that is currently in the registry, we can do the following:
- Register the
TypeIdtype as a new tag value with the IANA. This will hold up to a 64 bit value, and allows the compiler to create values independent of what is registered with the IANA.
- Create a method of setting the
TypeIdvalue for an object (possibly a new attribute that can be added to types).
- A method of determining if a given type's
TypeIdwas set (implying it was registered with the IANA), or arbitrarily chosen by the compiler.
The first point is necessary because if rust adopts the idea of keeping in sync with the IANA, then every time anyone creates any new type they would need to register it with the IANA or risk the
TypeId they choose getting assigned to a different type by the IANA. By creating and registering a new
TypeId value (maybe with the version of the compiler that produced it? I'm open to suggestions on what should go in here!), we can create values that are entirely independent of the IANA, and which never conflict with any registered values.
If a type is sufficiently important that someone is willing to register it with the IANA to get a permanent value for their
TypeId, then there will need to be a method of setting the
TypeId for that type. Registering with the IANA implies that the registrant expects their type is going to broadly useful and of sufficient importance that it's worth the effort of registration.
Nothing. I don't know if this will be a security issue or not, and it's something that would need more knowledgeable people than me to decide this.
Seriously? I don't know. The rust compiler has no direct concept of serialization, so I don't know if following this proposal would needlessly complicate the compiler, all without providing a seriously tangible benefit. Like I said at the start, I can't decide if this would be a good idea, or a bad one, and I need help deciding that.
1I'm well aware that there are a vast number of serialization crates out there that have already dealt with this problem. Part of the reason I'm throwing this idea out to everyone to critique is to see if this idea would improve the landscape for everyone.
For those that stumble on this and don't want to read the whole topic:
As noted in this post, if
TypeIds are given fixed values, then it becomes a soundness requirement that exactly one crate in the universe be permitted to use that value. Otherwise, if multiple crates use the same value for their own version of a given type, and someone compiles two or more of these crates into the same binary, then there is an implicit
transmute() buried within the code. This may or may not affect the behavior of the code (depends on the code involved), but implicit unsafe code is not what Rust is all about, so the idea is a bad idea.