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

Reply via email to