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 20f0df6a [FEAT] Add optional in-place permission to default structural 
descent (#781)
20f0df6a is described below

commit 20f0df6a38c1489cd035cf9702d533304c81bf96
Author: Tianqi Chen <[email protected]>
AuthorDate: Sun Sep 13 13:10:48 2026 -0400

    [FEAT] Add optional in-place permission to default structural descent (#781)
    
    Add optional `bool allow_inplace = true` to
    `StructuralMutatorObj::DefaultMaybeInplaceMutateExpected` so callbacks
    can forward their permission directly. False delegates to
    `DefaultMutateExpected`; true and omission preserve the existing
    behavior and ownership preconditions. Document the helper and simplify
    an existing callback.
    
    Validation: Debug C++ build, 69 existing structural tests, and
    changed-file checks passed.
---
 include/tvm/ffi/extra/structural_mutate.h | 15 ++++++++++++---
 tests/cpp/extra/test_structural_mutate.cc |  3 +--
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/include/tvm/ffi/extra/structural_mutate.h 
b/include/tvm/ffi/extra/structural_mutate.h
index 601d1bc6..06384b27 100644
--- a/include/tvm/ffi/extra/structural_mutate.h
+++ b/include/tvm/ffi/extra/structural_mutate.h
@@ -497,19 +497,28 @@ class StructuralMutatorObj : public Object {
   }
 
   /*!
-   * \brief Apply custom maybe-in-place mutation, or fall back to non-in-place 
mutation.
+   * \brief Apply default structural mutation with optional in-place 
permission.
    *
    * \param value The borrowed value to mutate.
+   * \param allow_inplace Whether in-place mutation is permitted. Defaults to 
true.
+   *        If false, call \ref DefaultMutateExpected.
    * \return The replacement or unchanged marker, or an Error if mutation 
failed. In-place
    *         changes completed before an Error are not rolled back.
    *
    * \note In-place mutation is explicitly opt-in. A registered
    *       ``__s_maybe_inplace_mutate__`` hook may rely on its input being 
safe to mutate and owns
    *       any variable-remap handling. When the hook is absent, this method 
calls
-   *       \ref DefaultMutateExpected.
+   *       \ref DefaultMutateExpected. This method does not check uniqueness. 
When
+   *       \p allow_inplace is true, the caller must already know that mutating
+   *       \p value in place is safe, including ownership of the path from the 
root.
+   *
+   * \code
+   * return mutator->DefaultMaybeInplaceMutateExpected(value, allow_inplace);
+   * \endcode
    */
   TVM_FFI_INLINE Expected<UnchangedOr<Any>> DefaultMaybeInplaceMutateExpected(
-      AnyView value) noexcept {
+      AnyView value, bool allow_inplace = true) noexcept {
+    if (!allow_inplace) return DefaultMutateExpected(value);
     return details::ExpectedUnsafe::MoveFromTVMFFIAny<UnchangedOr<Any>>(
         DefaultMaybeInplaceMutateRaw(value));
   }
diff --git a/tests/cpp/extra/test_structural_mutate.cc 
b/tests/cpp/extra/test_structural_mutate.cc
index 2866d1ca..5024613e 100644
--- a/tests/cpp/extra/test_structural_mutate.cc
+++ b/tests/cpp/extra/test_structural_mutate.cc
@@ -547,8 +547,7 @@ TEST(StructuralMutate, 
CallbackArityControlsInplaceMutation) {
           [&](const AnyArray& value, StructuralMutatorObj* mutator,
               bool allow_inplace) -> Expected<Any> {
             allow_inplace_trace.push_back(allow_inplace);
-            return allow_inplace ? 
mutator->DefaultMaybeInplaceMutateExpected(value)
-                                 : mutator->DefaultMutateExpected(value);
+            return mutator->DefaultMaybeInplaceMutateExpected(value, 
allow_inplace);
           },
           [&](int64_t value, StructuralMutatorObj*, bool allow_inplace) -> 
Expected<Any> {
             allow_inplace_trace.push_back(allow_inplace);

Reply via email to