Question:
|
| Member kind | Emitted identity |
|---|---|
| primitives only | EquivalenceHashComplete(...) |
bounded string<N> |
hash |
| array | hash |
@optional |
hash |
@appendable / @mutable struct |
hash |
typedef alias member |
None |
| enum member | None |
bounded sequence<T,N> member |
None |
| nested struct member | None on the container (the nested type itself gets a hash) |
So an identity is produced only for structs whose members are primitives, strings or arrays thereof. Any member that is a named or constructed type, or a sequence, suppresses it.
Illustration — the same struct with one member typed via an alias and via the primitive it aliases:
typedef unsigned long long MyId;
struct S { @key unsigned long long k; MyId m; }; // -> TypeIdentifier::None
struct S { @key unsigned long long k; unsigned long long m; }; // -> EquivalenceHashComplete([0xe0, 0x8d, 0x03, ...])Scale on a real IDL set
Across the five generated modules of a mid-size IDL set, the share of types carrying no identity ranged from roughly 4 in 10 to 3 in 4, settling near three quarters for the module covering the full type set.
Real IDL composes: nested header structs, enum-typed state fields, bounded sequences. The constructs that suppress the identity are exactly the ones that appear everywhere, so the proportion is high rather than incidental.
Why we are asking rather than asserting
Three readings seem possible and we cannot distinguish them from outside:
- Deliberate staging — hashing of composed types is not implemented yet,
Noneis the honest placeholder, and name-based matching is the accepted interim. If so, a note in theidl-rustdocs would help users size the gap. - Deliberate design —
Noneis meant to signal "no assertion about type identity", to be resolved by a live TypeRegistry lookup rather than a compile-time constant. TheDdsTypedoc comment mentions a "TypeRegistry lookup is live" case, which may be exactly this. - Oversight — the recursion into member types simply is not there.
What would help us
- Confirmation of which of the above applies.
- If (1) or (3): whether computing hashes for composed types is planned, and whether a
TypeRegistry-based path is the intended alternative in the meantime. - If (2): guidance on how a static type is expected to participate in
TypeMatcher::match_types, sinceTYPE_IDENTIFIERis aconstand the generated code sets no other identity.
We would also suggest that, whichever the answer, the silence is worth addressing: a type that carries no identity looks exactly like one that does, until you look at the generated constant. A generator diagnostic, or a note in the docs, would make it visible.
Method
Measured by generating our IDL baseline and counting the emitted TYPE_IDENTIFIER constants, plus single-construct cases to isolate the trigger. No source patch, unmodified published behaviour. Reproducers available on request.
Replies: 1 comment
|
Thank you again, @swarm59, for another very accurate report. No, this behaviour was not intended: emitting The Rust code-generation path had its own limited member-type resolver that understood primitive and string members but not the full named-type graph. A typedef, enum, sequence, map, nested struct, or another composed member could therefore collapse the identifier of the entire containing struct to The direct issue is fixed on Your report also led to a broader end-to-end audit of the complete XTypes identity path, from code generation through discovery and runtime matching. That audit uncovered several additional gaps:
Those paths have now been corrected as well. The affected bindings carry serialized TypeObjects through the typed-creation ABI, the matcher uses the populated TypeLookup registry, replies are routed to the requester’s advertised locator, and bitset/bitmask TypeObjects are included with byte-identity and bridge-roundtrip coverage. The wider runtime and binding work is included in One independently scoped XTypes limitation remains: mutually recursive type graphs still require the StronglyConnectedComponent identifier construction defined by XTypes 1.3 §7.3.4.9.2. The compiler currently detects and isolates those recursive SCCs instead of emitting a misleading ordinary equivalence hash. That work is tracked separately and does not affect the composed, non-recursive member cases reported here. The complete public I am closing this discussion as fixed. If a non-recursive composed type still produces Your continued careful testing has helped us strengthen the entire XTypes identity and matching pipeline, far beyond the original code-generation path. |
Thank you again, @swarm59, for another very accurate report. No, this behaviour was not intended: emitting
TypeIdentifier::Nonefor a struct merely because it contains a composed member silently disabled structural XTypes matching for a large part of normal application IDL.The Rust code-generation path had its own limited member-type resolver that understood primitive and string members but not the full named-type graph. A typedef, enum, sequence, map, nested struct, or another composed member could therefore collapse the identifier of the entire containing struct to
None, even though the full TypeObject mapping and hashing machinery already existed elsewhere in the compiler.The direct …