This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm-tirx.git
The following commit(s) were added to refs/heads/main by this push:
new 30bc80aeb [Rust] Update TVM FFI and explicit dispatch contracts (#178)
30bc80aeb is described below
commit 30bc80aebfc09bed76fdc637574374fe064fb52e
Author: Tianqi Chen <[email protected]>
AuthorDate: Tue Nov 3 17:17:47 2026 -0500
[Rust] Update TVM FFI and explicit dispatch contracts (#178)
Update TVM FFI to the latest merged source and adapt the Rust examples
to explicit dispatch argument/result contracts and managed interrupt
payloads. Raise the minimum Rust version to 1.95, align documentation CI
with that requirement, and update the affected guide signatures and API
links.
---
3rdparty/tvm-ffi | 2 +-
docs/README.md | 2 +-
docs/advanced/defining_ir_extensions.rst | 6 +++---
docs/advanced/extending_ir_in_rust.rst | 2 +-
docs/dev/doc_build.rst | 5 ++---
docs/ir_guides/working_with_ir_in_rust.rst | 28 +++++++++++++++-------------
examples/extension/README.md | 2 +-
examples/extension/src/lib.rs | 2 +-
examples/ir_guides/rust/src/lib.rs | 8 ++++----
rust/Cargo.toml | 2 +-
tests/scripts/task_python_docs.sh | 3 +--
11 files changed, 31 insertions(+), 31 deletions(-)
diff --git a/3rdparty/tvm-ffi b/3rdparty/tvm-ffi
index b0a048e4d..9c834dadb 160000
--- a/3rdparty/tvm-ffi
+++ b/3rdparty/tvm-ffi
@@ -1 +1 @@
-Subproject commit b0a048e4d510febff28f1ecea102716516c5b952
+Subproject commit 9c834dadb9d575be3818758f371d143720a1602a
diff --git a/docs/README.md b/docs/README.md
index 6250895ed..450554d89 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -27,7 +27,7 @@ uv run --no-sync python -m sphinx -b html -W docs
docs/_build/html
Set `BUILD_CPP_DOCS=1` to also generate the C++ API reference; this requires
Doxygen.
Set `BUILD_RUST_DOCS=1` to also generate the Rust API reference with `cargo
doc`; this
-requires Rust 1.85 or newer and the installed TIRx package, whose
`tvm-tirx-config`
+requires Rust 1.95 or newer and the installed TIRx package, whose
`tvm-tirx-config`
the crate's build script runs.
Open `docs/_build/html/index.html` to browse the Developer Manual and API
reference.
diff --git a/docs/advanced/defining_ir_extensions.rst
b/docs/advanced/defining_ir_extensions.rst
index ba65df853..7ec42e5f6 100644
--- a/docs/advanced/defining_ir_extensions.rst
+++ b/docs/advanced/defining_ir_extensions.rst
@@ -171,15 +171,15 @@ rewrites:
impl Lowering {
fn parts(&self, expr: &Expr) -> Result<(Expr, Expr)> { ... }
}
- #[dispatch(map)]
+ #[dispatch(map, (AnyView<'_>,), Result<Any>)]
impl Lowering {
fn map_sequence(&mut self, seq: SeqStmt) -> Result<Any> { ... }
:append: }
``bindings`` records each complex variable with its two scalar replacements,
and ``parts`` reads the real and imaginary parts of an operand, either a
-``complex(re, im)`` call or a variable already split. ``#[dispatch(map)]``
-sends each node to the ``map_`` method of its type, and leaves other nodes
+``complex(re, im)`` call or a variable already split.
+``#[dispatch(map, (AnyView<'_>,), Result<Any>)]`` sends each node to the
``map_`` method of its type, and leaves other nodes
unchanged: ``map_call`` applies the three rules, ``map_bind`` splits a complex
binding, and ``map_sequence`` flattens the sequence that a split binding leaves
inside another. The callback passes each node to ``lowering.dispatch`` and
diff --git a/docs/advanced/extending_ir_in_rust.rst
b/docs/advanced/extending_ir_in_rust.rst
index fe718306a..2a68bca4b 100644
--- a/docs/advanced/extending_ir_in_rust.rst
+++ b/docs/advanced/extending_ir_in_rust.rst
@@ -84,7 +84,7 @@ the code that ``#[dispatch]`` generates refers to the crate
by that name:
:language: toml
:start-at: [lib]
-First build and install TIRx from this checkout. With Rust 1.84 or newer,
+First build and install TIRx from this checkout. With Rust 1.95 or newer,
install the extension from the repository root in the same Python environment:
.. code-block:: bash
diff --git a/docs/dev/doc_build.rst b/docs/dev/doc_build.rst
index f41f21245..da0c05b1a 100644
--- a/docs/dev/doc_build.rst
+++ b/docs/dev/doc_build.rst
@@ -92,9 +92,8 @@ Build with Rust Docs
--------------------
The Rust API reference is the ``cargo doc`` output of the ``rust/`` crate,
copied
-under ``reference/rust/generated`` of the HTML output. Use Rust 1.85 or newer
to avoid
-the `Rust 1.84 rustdoc crash
<https://github.com/rust-lang/rust/issues/134715>`_
-when documenting ``tvm-ffi``. The crate's build script runs
+under ``reference/rust/generated`` of the HTML output. Use Rust 1.95 or newer,
+as required by the crate and its ``tvm-ffi`` dependency. The crate's build
script runs
``tvm-tirx-config`` to find ``libtvm_tirx_compiler``, so
build the package first; ``uv run`` puts the helper on ``PATH``. Set
``BUILD_RUST_DOCS=1`` to enable the extra step:
diff --git a/docs/ir_guides/working_with_ir_in_rust.rst
b/docs/ir_guides/working_with_ir_in_rust.rst
index ba8013e21..069eed066 100644
--- a/docs/ir_guides/working_with_ir_in_rust.rst
+++ b/docs/ir_guides/working_with_ir_in_rust.rst
@@ -314,12 +314,13 @@ struct. It works like a trait whose methods all have
default bodies: we
write methods for the node types we care about, and every other type gets
the default behavior.
-``#[dispatch(walk)]`` on an ``impl`` block turns its ``walk_*`` methods
-into callbacks for |structural_walk|_, which visits every node. Each
-method borrows the nodes of its parameter type, and the methods are tried
-in source order. Walk handlers share the ``Result<WalkResult>`` return type;
-one handler declares the trailing ``DefRegionKind`` argument used by the
-walker, and handlers that do not need it may omit it. Let's count the
+``#[dispatch(walk, (AnyView<'_>, DefRegionKind), Result<WalkResult>)]``
+on an ``impl`` block turns its ``walk_*`` methods into callbacks for
+|structural_walk|_, which visits every node. Each method borrows the nodes
+of its parameter type, and the methods are tried in source order. The
+attribute declares the argument tuple and ``Result<WalkResult>`` return type;
+handlers that
+do not need the trailing ``DefRegionKind`` may omit it. Let's count the
variables and additions:
.. literalinclude:: ../../examples/ir_guides/rust/src/lib.rs
@@ -523,9 +524,10 @@ Visitors and Mutators in Rust
Stateful traversals use the same four structural utilities. State lives
on a |dispatch|_ struct, as in Dispatching on Node Types.
-``#[dispatch(map)]`` and ``#[dispatch(visit)]`` group ``map_*`` and
-``visit_*`` methods. ``#[dispatch(mutate, MutationView)]`` groups
-``mutate_*`` methods and carries mutation permission through matching.
+The ``map``, ``visit``, and ``mutate`` prefixes group ``map_*``,
+``visit_*``, and ``mutate_*`` methods. Each attribute declares its
+argument tuple and return type; mutation uses ``MutationView`` as its
+first argument to carry mutation permission through matching.
**A visit or mutate callback takes control of its node's children.**
Let's record the loops around each write. Each handler receives the node
@@ -628,7 +630,7 @@ Quick Reference
- Receives the definition region kind
* - ``Function::get_global("ffi.StructuralEqual")``
- Compares by structure
- * - |dispatch|_\ ``(walk)``, ``(map)``, ``(visit)``, ``(mutate,
MutationView)``
+ * - |dispatch|_\ ``(prefix, (Carrier, ...), ResultType)``
- Turns the methods of a struct into typed callbacks
* - |StructuralVisitorView|_, |StructuralMutatorView|_
- Recurse with the same dispatcher and current definition region
@@ -648,15 +650,15 @@ Quick Reference
.. |try_cast| replace:: ``.try_cast()``
.. _try_cast:
../reference/rust/generated/tvm_ffi/object/trait.ObjectRefCast.html
.. |structural_walk| replace:: ``structural_walk``
-.. _structural_walk:
../reference/rust/generated/tvm_ffi/extra/structural_visit/fn.structural_walk.html
+.. _structural_walk:
../reference/rust/generated/tvm_ffi/extra/structural_walk/fn.structural_walk.html
.. |structural_map| replace:: ``structural_map``
-.. _structural_map:
../reference/rust/generated/tvm_ffi/extra/structural_mutate/fn.structural_map.html
+.. _structural_map:
../reference/rust/generated/tvm_ffi/extra/structural_map/fn.structural_map.html
.. |structural_visit| replace:: ``structural_visit``
.. _structural_visit:
../reference/rust/generated/tvm_ffi/extra/structural_visit/fn.structural_visit.html
.. |structural_mutate| replace:: ``structural_mutate``
.. _structural_mutate:
../reference/rust/generated/tvm_ffi/extra/structural_mutate/fn.structural_mutate.html
.. |WalkResult| replace:: ``WalkResult``
-.. _WalkResult:
../reference/rust/generated/tvm_ffi/extra/structural_visit/enum.WalkResult.html
+.. _WalkResult:
../reference/rust/generated/tvm_ffi/extra/structural_walk/enum.WalkResult.html
.. |DefRegionKind| replace:: ``DefRegionKind``
.. _DefRegionKind:
../reference/rust/generated/tvm_ffi/extra/structural_visit/enum.DefRegionKind.html
.. |make_const| replace:: ``make_const``
diff --git a/examples/extension/README.md b/examples/extension/README.md
index 8e2928abe..ff1b32141 100644
--- a/examples/extension/README.md
+++ b/examples/extension/README.md
@@ -30,7 +30,7 @@ pipeline. The tutorial in `docs/advanced/` walks through the
code.
## Install and Run
-After building and installing TIRx from this checkout, with Rust 1.84 or newer,
+After building and installing TIRx from this checkout, with Rust 1.95 or newer,
run from the repository root in the same Python environment:
```bash
diff --git a/examples/extension/src/lib.rs b/examples/extension/src/lib.rs
index 778150c0d..d1438a486 100644
--- a/examples/extension/src/lib.rs
+++ b/examples/extension/src/lib.rs
@@ -192,7 +192,7 @@ impl Lowering {
}
}
-#[dispatch(map)]
+#[dispatch(map, (AnyView<'_>,), Result<Any>)]
impl Lowering {
fn map_sequence(&mut self, seq: SeqStmt) -> Result<Any> {
Ok(SeqStmt::new(seq.seq.iter(), seq.loc.clone()).into())
diff --git a/examples/ir_guides/rust/src/lib.rs
b/examples/ir_guides/rust/src/lib.rs
index 65d901473..d52d2edb8 100644
--- a/examples/ir_guides/rust/src/lib.rs
+++ b/examples/ir_guides/rust/src/lib.rs
@@ -125,7 +125,7 @@ fn first_write(func: Function) ->
Result<Option<TensorStore>> {
let find_write = |store: TensorStore| WalkResult::interrupt_with(store);
let found = tvm_ffi::structural_walk(&func, find_write,
WalkOrder::PostOrder)?;
match found {
- Some(interrupt) => Ok(Some(interrupt.value.try_into()?)),
+ Some(interrupt) => Ok(Some(interrupt.value.clone().try_into()?)),
None => Ok(None),
}
}
@@ -177,7 +177,7 @@ struct Counter {
adds: usize,
}
-#[dispatch(walk)]
+#[dispatch(walk, (AnyView<'_>, DefRegionKind), Result<WalkResult>)]
impl Counter {
fn walk_var(&mut self, _var: &VarObj, _kind: DefRegionKind) ->
Result<WalkResult> {
self.vars += 1;
@@ -207,7 +207,7 @@ struct LoopNest {
writes: Vec<String>,
}
-#[dispatch(visit)]
+#[dispatch(visit, (AnyView<'_>, &mut StructuralVisitorView<'_, Self>),
Result<Option<VisitInterrupt>>)]
impl LoopNest {
fn visit_for(
&mut self,
@@ -242,7 +242,7 @@ struct ReverseLoops {
reversed_index: HashMap<ObjectIdentity, Expr>,
}
-#[dispatch(mutate, MutationView)]
+#[dispatch(mutate, (MutationView<'_>, &mut StructuralMutatorView<'_, Self>),
Result<Any>)]
impl ReverseLoops {
fn mutate_for(
&mut self,
diff --git a/rust/Cargo.toml b/rust/Cargo.toml
index c2722e2fa..8a491e2b5 100644
--- a/rust/Cargo.toml
+++ b/rust/Cargo.toml
@@ -20,7 +20,7 @@ name = "tvm-tirx"
version = "0.1.0-alpha.5"
edition = "2021"
# The oldest toolchain that builds the crate and tvm-ffi; CMake checks cargo
against it.
-rust-version = "1.84"
+rust-version = "1.95"
description = "Rust API for the TVM TIRx compiler: IR bindings and IR
extensions"
license = "Apache-2.0"
homepage = "https://tvm.apache.org/tirx/"
diff --git a/tests/scripts/task_python_docs.sh
b/tests/scripts/task_python_docs.sh
index 3831e3b72..91e0c07c2 100755
--- a/tests/scripts/task_python_docs.sh
+++ b/tests/scripts/task_python_docs.sh
@@ -23,8 +23,7 @@ source ./tests/scripts/test_task_install_dist_wheels.sh
--group docs
uv pip install mlc-doxygen-bin==1.17.0
# cargo for the Rust API reference; the crate's build script finds the
installed wheel's
# libtvm_tirx_compiler through the tvm-tirx-config of the activated .venv.
-# Rust 1.84's rustdoc crashes on proc-macro doc links (rust-lang/rust#134715).
-source ./tests/scripts/task_install_rust.sh 1.85.1
+source ./tests/scripts/task_install_rust.sh
rm -rf docs/_build docs/reference/python/generated
export DOXYGEN_NUM_PROC_THREADS=0
BUILD_CPP_DOCS=1 BUILD_RUST_DOCS=1 uv run --no-sync python -m sphinx -j auto
-E -a -b html -d docs/_build/doctrees -W --keep-going docs docs/_build/html