[STUBGEN][RUST] Generate complete object mirrors and allocators - #740
Merged
tlopex merged 8 commits intoSep 4, 2026
Merged
Conversation
Signed-off-by: yuchuan <yuchuan.7streams@gmail.com>
Signed-off-by: yuchuan <yuchuan.7streams@gmail.com>
A type under a builtin such as `ffi.Enum` embeds a header-only stand-in for it, but the classifier judged the builtin from its registry bytes and called a fieldless `testing.TestEnumVariant` complete: the generated struct then asserted `size_of == 48` on 24 bytes and grew allocators. `layout.classify` gains an `unmirrored` set and a `no-mirror` reason for types whose bytes the target never reproduces; the Rust backend passes every builtin ancestor below `ffi.Object`, so such types and everything under them stay opaque with an explanatory verdict. Signed-off-by: yuchuan <yuchuan.7streams@gmail.com>
Signed-off-by: yuchuan <yuchuan.7streams@gmail.com>
Signed-off-by: yuchuan <yuchuan.7streams@gmail.com>
Seven-Streams
force-pushed
the
main-dev/2026-09-03/stubgen_rust_complete
branch
from
September 4, 2026 19:33
a6229b6 to
ef00323
Compare
Seven-Streams
marked this pull request as ready for review
September 4, 2026 19:39
tlopex
approved these changes
Sep 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Attach the layout classifier (#730) to the Rust backend. A type whose layout the registry proves is now bound complete: a
#[repr(C)]struct with every physical field at its reflected offset and width, aconstsize/alignment assertion, and a lossless allocator (<Leaf>Obj::newcrate-private,<Leaf>::newpublic). Everything else keeps the opaque form of #738. Three new directives:opaquevetoes a reproducible layout,upcastadds a hand-written typed view,custom-newrenames the generated allocator tofrom_complete_fieldsso a hand-writtennewcan own the name.Motivation
This is what tvm-rust-ext's
STUBGEN_FEEDBACK.mdasks for: ordinary data nodes allocated in Rust from their complete fields, polymorphic and unreflected-byte types kept opaque. Generatingir./tirx./arith./target.from tvm-rust-ext'slibtvm_compiler.sogives 131 types (98 complete, 33 opaque) that compile against the crate without edits; the differences from the hand-written bindings are exactly what the directives cover.Changes
stub/layout.py:classify(..., unmirrored=...)and theno-mirrorreason, so types under a builtin parent (ffi.Enum, ...) stay opaque: their base is only a header-only stand-in.rust_generator/codegen.py: classify each object with its ancestors; mirror fields (scalars by reflected width,Optional<T>asOption<T>ortvm_ffi::Optional<T>by payload, directive widths checked against the field size); render the complete struct and its allocators;upcastandcustom-newhandling.rust_generator/directives.py,consts.py: the three directives and the width tables.rust_generator/utils.py: a reflected field namedbaseordatais spelledbase_/data_, since those are the generated struct's own members (TVM hastirx.Ramp.base,tirx.DeclBuffer.data).examples/rust_stubgen/:IntPairis now a plain data object, allocated from Rust with the generatedIntPair::newand read back by C++.Testing
test_stubgen_rust.py(36 cases),test_stubgen.py,test_stub_layout.py: 121 passed; ruff clean. The example regenerates an identicalmod.rsandcargo runprintsa=1 b=2 kind=PairKind(1)andsum=3.