Skip to content

Add const XDR serialization on Ref types - #562

Draft
leighmcculloch wants to merge 10 commits into
generated-ref-typesfrom
const-xdr-serialization
Draft

Add const XDR serialization on Ref types#562
leighmcculloch wants to merge 10 commits into
generated-ref-typesfrom
const-xdr-serialization

Conversation

@leighmcculloch

@leighmcculloch leighmcculloch commented Jul 28, 2026

Copy link
Copy Markdown
Member

Note

Part of a stack of PRs that must merge in this order.

A first group of PRs deliver const-encoded contract specs, so that contract specs are produced at compile time instead of at proc-macro execution time. This provides the foundation for the capability to construct the specs from information that is not known at proc-macro execution and only known at compile time, like the fully qualified name of a type:

  1. Add borrowed Ref variants of generated types #560
  2. Add const XDR serialization on Ref types #562 ← this PR
  3. Encode contract spec XDR at const evaluation time rs-soroban-sdk#1965

A second group of PRs deliver fully qualified type names in contract specs. Instead of a type having the name Context it will have the name soroban_sdk::auth::Context. Qualified type names make it possible to uniquely identify types in the spec, even when they have the same name. This resolves several problems with contract specs the type identify problem (stellar/rs-soroban-sdk#1570), type aliases limitations (stellar/rs-soroban-sdk#1857), and optimise spec shaking data section size (stellar/rs-soroban-sdk#1978):

  1. Widen user-defined type name limit stellar-xdr#312
  2. Regenerate with widened UDT name limit #566
  3. Qualify user-defined type names rs-soroban-sdk#1970

What

Add a const feature giving every generated type const XDR serializers: const_write_xdr, which writes into a new const ConstWriter; const_to_xdr, which returns a fixed-size [u8; N]; and const_xdr_len, which gives that length. They live on the borrowing Ref form for types that own heap data and on the type itself for the rest, so a value can be built from borrowed data and serialized straight into a fixed byte array at compile time.

Why

XDR encoding was runtime-only, behind the std-gated WriteXdr trait, so bytes couldn't be produced in a const context. It has to live on the Ref types because an owned VecM/BytesM/StringM holds a Vec, whose destructor can't run during const evaluation (E0493); the Ref types borrow instead, have no destructor, and are freely usable in const. The const encoders mirror the owned types' WriteXdr::write_xdr statement for statement, including the same depth and length accounting, so output is byte-identical. The const feature depends on nothing, so a fixed XDR value can be baked into a const in a no_std, no-alloc build.

Known limitations

Not built on the WriteXdr trait, since const traits aren't stable, so it is a parallel set of inherent functions rather than a trait impl.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant