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-ffi.git
The following commit(s) were added to refs/heads/main by this push:
new 1279f634 [REFACTOR][EXTRA] Add TVM_FFI_S_VISIT_RETURN_NONE for visit
hook tails (#753)
1279f634 is described below
commit 1279f6346e97a3c68ded753ce9819635efe19418
Author: Tianqi Chen <[email protected]>
AuthorDate: Sun Sep 6 10:28:08 2026 -0400
[REFACTOR][EXTRA] Add TVM_FFI_S_VISIT_RETURN_NONE for visit hook tails
(#753)
A visit hook ends by returning "no interrupt", which every hook
currently spells
out by hand:
```cpp
return
ExpectedUnsafe::MoveToTVMFFIAny(Expected<Optional<VisitInterrupt>>(std::nullopt));
```
That puts the `Expected` storage representation into every hook body,
including
downstream ones outside this repository, where it would keep compiling
if the
representation ever changed.
`TVM_FFI_S_VISIT_MAYBE_EARLY_RETURN` already owns the other half of this
ABI
boundary; the tail was the only part still written by hand. This adds
the
terminal counterpart, going through the same `MaybeReturnHelper` proxy
so it
works from a raw `TVMFFIAny` hook and a typed helper alike, adopts it in
the
container hooks, and documents the canonical hook shape once beside the
macro
pair.
---
include/tvm/ffi/extra/structural_visit.h | 41 ++++++++++++++++++++++++++++----
src/ffi/extra/structural_visit.cc | 4 ++--
2 files changed, 39 insertions(+), 6 deletions(-)
diff --git a/include/tvm/ffi/extra/structural_visit.h
b/include/tvm/ffi/extra/structural_visit.h
index b8d41948..f2f7e830 100644
--- a/include/tvm/ffi/extra/structural_visit.h
+++ b/include/tvm/ffi/extra/structural_visit.h
@@ -487,9 +487,31 @@ enum class WalkOrder : int32_t {
namespace details {
-/// \cond Doxygen_Suppress
-// Return from the current raw or same-T Expected visit function if Result
stops traversal.
-// The rvalue-only proxy lets the enclosing return type select the
representation.
+/*!
+ * \brief Return from a visit hook if \p Result stops traversal.
+ *
+ * Propagates an ``Error`` or a ``VisitInterrupt`` out of the enclosing
function
+ * and otherwise falls through. Works from a raw ``TVMFFIAny`` hook and from a
+ * typed ``Expected`` helper alike; the rvalue-only proxy lets the return type
+ * select the representation.
+ *
+ * A registered ``__s_visit__`` hook is one line per traversed field followed
by
+ * the terminal return. A field skipped on purpose is guarded by a condition
and
+ * carries a ``// skips:`` note saying why.
+ *
+ * \code{.cpp}
+ * TVMFFIAny FooVisit(StructuralVisitorObj* visitor, AnyView value) noexcept {
+ * const FooNode* self =
+ * details::AnyUnsafe::RawObjectPtrFromAnyViewAfterCheck<const
FooNode>(value);
+ * TVM_FFI_S_VISIT_MAYBE_EARLY_RETURN(visitor->VisitExpected(self->a));
+ * TVM_FFI_S_VISIT_MAYBE_EARLY_RETURN(visitor->VisitExpected(self->b));
+ * TVM_FFI_S_VISIT_RETURN_NONE();
+ * }
+ * \endcode
+ *
+ * \param Result An expression yielding the descent result to inspect.
+ * \sa TVM_FFI_S_VISIT_RETURN_NONE
+ */
#define TVM_FFI_S_VISIT_MAYBE_EARLY_RETURN(Result)
\
do {
\
auto&& tvm_ffi_res_ = (Result);
\
@@ -498,7 +520,18 @@ namespace details {
return
::tvm::ffi::details::MaybeReturnHelper(::std::move(tvm_ffi_res_)); \
}
\
} while (0)
-/// \endcond
+
+/*!
+ * \brief Return the completed result -- no interrupt -- from a visit hook.
+ *
+ * Terminal statement of a hook that traversed every field it intends to. Works
+ * from a raw ``TVMFFIAny`` hook and a typed ``Expected`` helper alike.
+ *
+ * \sa TVM_FFI_S_VISIT_MAYBE_EARLY_RETURN
+ */
+#define TVM_FFI_S_VISIT_RETURN_NONE() \
+ return ::tvm::ffi::details::MaybeReturnHelper( \
+
::tvm::ffi::Expected<::tvm::ffi::Optional<::tvm::ffi::VisitInterrupt>>(::std::nullopt))
} // namespace details
diff --git a/src/ffi/extra/structural_visit.cc
b/src/ffi/extra/structural_visit.cc
index e1f73a5f..2549b670 100644
--- a/src/ffi/extra/structural_visit.cc
+++ b/src/ffi/extra/structural_visit.cc
@@ -115,7 +115,7 @@ TVMFFIAny VisitSeqContainer(StructuralVisitorObj* visitor,
const SeqBaseObj* sel
for (const Any& item : *self) {
TVM_FFI_S_VISIT_MAYBE_EARLY_RETURN(visitor->VisitExpected(item));
}
- return
ExpectedUnsafe::MoveToTVMFFIAny(Expected<Optional<VisitInterrupt>>(std::nullopt));
+ TVM_FFI_S_VISIT_RETURN_NONE();
}
/*! \brief Visit values in a map container while treating keys as structural
anchors. */
@@ -123,7 +123,7 @@ TVMFFIAny VisitMapContainer(StructuralVisitorObj* visitor,
const MapBaseObj* sel
for (const auto& kv : *self) {
TVM_FFI_S_VISIT_MAYBE_EARLY_RETURN(visitor->VisitExpected(kv.second));
}
- return
ExpectedUnsafe::MoveToTVMFFIAny(Expected<Optional<VisitInterrupt>>(std::nullopt));
+ TVM_FFI_S_VISIT_RETURN_NONE();
}
/*! \brief Structural visit hook for ArrayObj. */