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 fc5294cb8 [Rust] Bump tvm-ffi to apache/tvm-ffi#940 (copy-on-write 
visit error context) (#210)
fc5294cb8 is described below

commit fc5294cb87398161447cdc02061ef2a851f67411
Author: Tianqi Chen <[email protected]>
AuthorDate: Fri Nov 6 07:28:20 2026 -0500

    [Rust] Bump tvm-ffi to apache/tvm-ffi#940 (copy-on-write visit error 
context) (#210)
    
    Bumps tvm-ffi to apache/tvm-ffi#940, which includes #939: the visit
    error context is copy-on-write, and Rust appends it in place.
    
    - **Pointer API:** `UpdateVisitErrorContext` takes the `Error` or
    `Expected` result by pointer, as it may replace a shared `Error` with an
    annotated copy. The functor dispatchers, the simplifier and iter-map
    rewriter, and the constraint-context visitor and mutator pass the caught
    `Error` by address.
    - **Annotate the result, not a second handle:** the constraint-context
    mutator's hook boundary passed `result.error()` through a second handle.
    Under copy-on-write that handle would get the annotated copy and the
    frame would be lost, so it now passes `&result`.
    - **No copy on the mutator's dedupe check:** the constraint-context
    mutator now checks whether the frame is already named without keeping a
    context handle alive across the update, so a uniquely held context is
    appended in place.
    - **Regenerated bindings** drop the `SAFETY` comments on the generated
    `ImmutableObject` impls.
    - **Tests:** a functor that throws an `Error` it also holds now sees the
    context land on a copy, so the three error-context tests check that the
    held `Error` stays unannotated, not that the thrown one keeps its
    identity.
---
 3rdparty/tvm-ffi                                   |  2 +-
 include/tvm/ir/expr_functor.h                      |  2 +-
 include/tvm/ir/object_functor.h                    |  6 +--
 include/tvm/tirx/stmt_functor.h                    |  2 +-
 .../structural_mutate_with_constraint_context.h    |  3 +-
 rust/src/backend/cuda/op.rs                        |  6 ---
 rust/src/ir/attrs.rs                               |  4 --
 rust/src/ir/base.rs                                |  2 -
 rust/src/ir/expr.rs                                | 36 ---------------
 rust/src/ir/function.rs                            |  2 -
 rust/src/ir/global_info.rs                         |  2 -
 rust/src/ir/location.rs                            | 10 ----
 rust/src/ir/op.rs                                  |  2 -
 rust/src/ir/prim/expr.rs                           | 54 ----------------------
 rust/src/ir/prim/vector_expr.rs                    |  6 ---
 rust/src/ir/stmt.rs                                | 26 -----------
 rust/src/ir/transform/core.rs                      |  8 ----
 rust/src/ir/type.rs                                | 22 ---------
 rust/src/runtime.rs                                |  2 -
 rust/src/sym/analyzer.rs                           |  6 ---
 rust/src/sym/constraint.rs                         |  8 ----
 rust/src/sym/int_set.rs                            |  2 -
 rust/src/sym/iter_affine_map.rs                    |  6 ---
 rust/src/tirx/function.rs                          |  2 -
 rust/src/tirx/index_map.rs                         |  2 -
 rust/src/tirx/layout.rs                            |  8 ----
 rust/src/tirx/op.rs                                |  2 -
 rust/src/tirx/tensor.rs                            |  2 -
 rust/src/tirx/thread_scope.rs                      |  2 -
 rust/src/tirx/tile/dispatch.rs                     |  2 -
 rust/src/tirx/tile/instruction.rs                  |  4 --
 rust/src/tirx/transform/function_pass.rs           |  2 -
 rust/src/tirx/transform/transform.rs               |  4 --
 rust/src/tirx/type.rs                              |  2 -
 src/sym/canonical_simplify.cc                      |  2 +-
 src/sym/iter_affine_map.cc                         |  2 +-
 .../ir/stmt_functor_with_constraint_context.cc     | 14 +++---
 tests/cpp/ir/expr_functor_test.cc                  |  7 ++-
 .../stmt_functor_with_constraint_context_test.cc   |  4 +-
 39 files changed, 25 insertions(+), 255 deletions(-)

diff --git a/3rdparty/tvm-ffi b/3rdparty/tvm-ffi
index 5fdba0f4c..9288282fe 160000
--- a/3rdparty/tvm-ffi
+++ b/3rdparty/tvm-ffi
@@ -1 +1 @@
-Subproject commit 5fdba0f4c562465435ab4a860da602ab80f6820d
+Subproject commit 9288282fee38e0ba681411b80bb36d211d436e60
diff --git a/include/tvm/ir/expr_functor.h b/include/tvm/ir/expr_functor.h
index 374d78136..0711f80ac 100644
--- a/include/tvm/ir/expr_functor.h
+++ b/include/tvm/ir/expr_functor.h
@@ -73,7 +73,7 @@ class ExprFunctor<R(const Expr&, Args...)> {
     try {
       return (*vtable_)(node, this, std::forward<Args>(args)...);
     } catch (ffi::Error& error) {
-      ffi::detail::UpdateVisitErrorContext(error, node);
+      ffi::detail::UpdateVisitErrorContext(&error, node);
       throw;
     }
   }
diff --git a/include/tvm/ir/object_functor.h b/include/tvm/ir/object_functor.h
index 982d691fb..616be8da8 100644
--- a/include/tvm/ir/object_functor.h
+++ b/include/tvm/ir/object_functor.h
@@ -246,7 +246,7 @@ class TVM_TIRX_DLL ObjectVisitor : public 
ffi::StructuralVisitorObj {
       try {
         return (*native_vtable_)(object, this);
       } catch (ffi::Error& error) {
-        ffi::detail::UpdateVisitErrorContext(error, 
ffi::GetRef<ffi::ObjectRef>(object));
+        ffi::detail::UpdateVisitErrorContext(&error, 
ffi::GetRef<ffi::ObjectRef>(object));
         throw;
       }
     }
@@ -310,7 +310,7 @@ class TVM_TIRX_DLL ObjectVisitor : public 
ffi::StructuralVisitorObj {
       // DefaultVisitExpected does not name the current node; 
DefaultMutateExpected does.
       return ffi::StructuralVisitorObj::DefaultVisitExpected(value).value();
     } catch (ffi::Error& error) {
-      ffi::detail::UpdateVisitErrorContext(error, value);
+      ffi::detail::UpdateVisitErrorContext(&error, value);
       throw;
     }
   }
@@ -386,7 +386,7 @@ class TVM_TIRX_DLL ObjectMutator : public 
ffi::StructuralMapEngineBase {
       try {
         return (*native_vtable_)(object, this, inplace_mode);
       } catch (ffi::Error& error) {
-        ffi::detail::UpdateVisitErrorContext(error, 
ffi::GetRef<ffi::ObjectRef>(object));
+        ffi::detail::UpdateVisitErrorContext(&error, 
ffi::GetRef<ffi::ObjectRef>(object));
         throw;
       }
     }
diff --git a/include/tvm/tirx/stmt_functor.h b/include/tvm/tirx/stmt_functor.h
index 60e97354a..78428c9c4 100644
--- a/include/tvm/tirx/stmt_functor.h
+++ b/include/tvm/tirx/stmt_functor.h
@@ -72,7 +72,7 @@ class StmtFunctor<R(const Stmt&, Args...)> {
     try {
       return (*vtable_)(node, this, std::forward<Args>(args)...);
     } catch (ffi::Error& error) {
-      ffi::detail::UpdateVisitErrorContext(error, node);
+      ffi::detail::UpdateVisitErrorContext(&error, node);
       throw;
     }
   }
diff --git a/include/tvm/tirx/structural_mutate_with_constraint_context.h 
b/include/tvm/tirx/structural_mutate_with_constraint_context.h
index b5fa84c8b..5b735e661 100644
--- a/include/tvm/tirx/structural_mutate_with_constraint_context.h
+++ b/include/tvm/tirx/structural_mutate_with_constraint_context.h
@@ -227,8 +227,7 @@ 
StructuralMutatorWithConstraintContextObj::DefaultMutateExpected(ffi::AnyView va
   }
   auto result = 
ffi::details::ExpectedUnsafe::MoveFromTVMFFIAny<ffi::UnchangedOr<ffi::Any>>(raw);
   if (result.is_err()) {
-    auto error = result.error();
-    ffi::details::UpdateVisitErrorContext(error, value);
+    ffi::detail::UpdateVisitErrorContext(&result, value);
   }
   return result;
 }
diff --git a/rust/src/backend/cuda/op.rs b/rust/src/backend/cuda/op.rs
index 2717fd4d9..269959368 100644
--- a/rust/src/backend/cuda/op.rs
+++ b/rust/src/backend/cuda/op.rs
@@ -156,8 +156,6 @@ impl TCGen05InstrDescriptorAttrs {
     }
 }
 
-// SAFETY: `tirx.cuda.TCGen05InstrDescriptorAttrs` is not `_type_mutable`: a 
shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for 
TCGen05InstrDescriptorAttrsObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(TCGen05InstrDescriptorAttrs => Attrs);
@@ -291,8 +289,6 @@ impl TCGen05InstrDescriptorBlockScaledAttrs {
     }
 }
 
-// SAFETY: `tirx.cuda.TCGen05InstrDescriptorBlockScaledAttrs` is not 
`_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for 
TCGen05InstrDescriptorBlockScaledAttrsObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(TCGen05InstrDescriptorBlockScaledAttrs => 
Attrs);
@@ -388,8 +384,6 @@ impl TensorMapEncodeTiledAttr {
     }
 }
 
-// SAFETY: `tirx.cuda.TensorMapEncodeTiledAttr` is not `_type_mutable`: a 
shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for TensorMapEncodeTiledAttrObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(TensorMapEncodeTiledAttr => Attrs);
diff --git a/rust/src/ir/attrs.rs b/rust/src/ir/attrs.rs
index 28a17eb32..80a841534 100644
--- a/rust/src/ir/attrs.rs
+++ b/rust/src/ir/attrs.rs
@@ -106,8 +106,6 @@ unsafe impl UnsafeInit for AttrsObj {
     }
 }
 
-// SAFETY: `ir.Attrs` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for AttrsObj {}
 // tvm-ffi-stubgen(end)
 
@@ -162,8 +160,6 @@ impl DictAttrs {
     }
 }
 
-// SAFETY: `ir.DictAttrs` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for DictAttrsObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(DictAttrs => Attrs);
diff --git a/rust/src/ir/base.rs b/rust/src/ir/base.rs
index b375d3941..1b3064012 100644
--- a/rust/src/ir/base.rs
+++ b/rust/src/ir/base.rs
@@ -90,7 +90,5 @@ impl EnvFunc {
     }
 }
 
-// SAFETY: `ir.EnvFunc` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for EnvFuncObj {}
 // tvm-ffi-stubgen(end)
diff --git a/rust/src/ir/expr.rs b/rust/src/ir/expr.rs
index 27021fb70..b683173c2 100644
--- a/rust/src/ir/expr.rs
+++ b/rust/src/ir/expr.rs
@@ -206,8 +206,6 @@ unsafe impl UnsafeInit for ExprObj {
     }
 }
 
-// SAFETY: `ir.Expr` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for ExprObj {}
 // tvm-ffi-stubgen(end)
 
@@ -714,8 +712,6 @@ unsafe impl UnsafeInit for StagingExprObj {
     }
 }
 
-// SAFETY: `ir.StagingExpr` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for StagingExprObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(StagingExpr => Expr);
@@ -784,8 +780,6 @@ unsafe impl UnsafeInit for OpaqueExprObj {
     }
 }
 
-// SAFETY: `ir.OpaqueExpr` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for OpaqueExprObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(OpaqueExpr => Expr);
@@ -846,8 +840,6 @@ impl GlobalVar {
     }
 }
 
-// SAFETY: `ir.GlobalVar` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for GlobalVarObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(GlobalVar => Expr);
@@ -916,8 +908,6 @@ impl Tuple {
     }
 }
 
-// SAFETY: `ir.Tuple` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for TupleObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Tuple => Expr);
@@ -1000,8 +990,6 @@ impl TupleGetItem {
     }
 }
 
-// SAFETY: `ir.TupleGetItem` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for TupleGetItemObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(TupleGetItem => Expr);
@@ -1114,8 +1102,6 @@ impl TensorLoad {
     }
 }
 
-// SAFETY: `ir.TensorLoad` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for TensorLoadObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(TensorLoad => Expr, TensorLoad => 
PrimExpr);
@@ -1220,8 +1206,6 @@ unsafe impl UnsafeInit for ConstantObj {
     }
 }
 
-// SAFETY: `ir.Constant` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for ConstantObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Constant => Expr);
@@ -1278,8 +1262,6 @@ impl FloatImm {
     }
 }
 
-// SAFETY: `ir.FloatImm` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for FloatImmObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(FloatImm => Expr, FloatImm => Constant, 
FloatImm => PrimExpr);
@@ -1480,8 +1462,6 @@ impl IntImm {
     }
 }
 
-// SAFETY: `ir.IntImm` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for IntImmObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(IntImm => Expr, IntImm => Constant, IntImm 
=> PrimExpr);
@@ -1683,8 +1663,6 @@ impl GenericConst {
     }
 }
 
-// SAFETY: `ir.GenericConst` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for GenericConstObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(GenericConst => Expr, GenericConst => 
Constant);
@@ -1780,8 +1758,6 @@ impl DataTypeImm {
     }
 }
 
-// SAFETY: `ir.DataTypeImm` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for DataTypeImmObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(DataTypeImm => Expr, DataTypeImm => 
Constant);
@@ -1851,8 +1827,6 @@ impl StringImm {
     }
 }
 
-// SAFETY: `ir.StringImm` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for StringImmObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(StringImm => Expr, StringImm => Constant);
@@ -1941,8 +1915,6 @@ impl Call {
     }
 }
 
-// SAFETY: `ir.Call` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for CallObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Call => Expr);
@@ -2080,8 +2052,6 @@ impl TensorRegion {
     }
 }
 
-// SAFETY: `ir.TensorRegion` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for TensorRegionObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(TensorRegion => Expr);
@@ -2169,8 +2139,6 @@ unsafe impl UnsafeInit for VarObj {
     }
 }
 
-// SAFETY: `ir.Var` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for VarObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Var => Expr);
@@ -2290,8 +2258,6 @@ impl LambdaExpr {
     }
 }
 
-// SAFETY: `ir.LambdaExpr` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for LambdaExprObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(LambdaExpr => Expr, LambdaExpr => 
StagingExpr);
@@ -2377,8 +2343,6 @@ impl Range {
     }
 }
 
-// SAFETY: `ir.Range` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for RangeObj {}
 // tvm-ffi-stubgen(end)
 
diff --git a/rust/src/ir/function.rs b/rust/src/ir/function.rs
index 447176f57..9c6e72e52 100644
--- a/rust/src/ir/function.rs
+++ b/rust/src/ir/function.rs
@@ -134,8 +134,6 @@ unsafe impl UnsafeInit for BaseFuncObj {
     }
 }
 
-// SAFETY: `ir.BaseFunc` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for BaseFuncObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(BaseFunc => Expr);
diff --git a/rust/src/ir/global_info.rs b/rust/src/ir/global_info.rs
index d632355f6..6ddebd1f2 100644
--- a/rust/src/ir/global_info.rs
+++ b/rust/src/ir/global_info.rs
@@ -88,7 +88,5 @@ unsafe impl UnsafeInit for GlobalInfoObj {
     }
 }
 
-// SAFETY: `ir.GlobalInfo` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for GlobalInfoObj {}
 // tvm-ffi-stubgen(end)
diff --git a/rust/src/ir/location.rs b/rust/src/ir/location.rs
index 9d24336cd..1faeb66fc 100644
--- a/rust/src/ir/location.rs
+++ b/rust/src/ir/location.rs
@@ -112,8 +112,6 @@ unsafe impl UnsafeInit for LocationObj {
     }
 }
 
-// SAFETY: `ir.Location` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for LocationObj {}
 // tvm-ffi-stubgen(end)
 
@@ -175,8 +173,6 @@ impl UnknownLoc {
     }
 }
 
-// SAFETY: `ir.UnknownLoc` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for UnknownLocObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(UnknownLoc => Location);
@@ -279,8 +275,6 @@ impl SourceLoc {
     }
 }
 
-// SAFETY: `ir.SourceLoc` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for SourceLocObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(SourceLoc => Location);
@@ -340,8 +334,6 @@ impl CallSiteLoc {
     }
 }
 
-// SAFETY: `ir.CallSiteLoc` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for CallSiteLocObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(CallSiteLoc => Location);
@@ -393,8 +385,6 @@ impl SourceName {
     }
 }
 
-// SAFETY: `ir.SourceName` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for SourceNameObj {}
 // tvm-ffi-stubgen(end)
 
diff --git a/rust/src/ir/op.rs b/rust/src/ir/op.rs
index a6a452e06..5ba6274c9 100644
--- a/rust/src/ir/op.rs
+++ b/rust/src/ir/op.rs
@@ -313,8 +313,6 @@ impl ArgumentInfo {
     }
 }
 
-// SAFETY: `ir.ArgumentInfo` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for ArgumentInfoObj {}
 // tvm-ffi-stubgen(end)
 
diff --git a/rust/src/ir/prim/expr.rs b/rust/src/ir/prim/expr.rs
index 3b176d98a..6222fd31a 100644
--- a/rust/src/ir/prim/expr.rs
+++ b/rust/src/ir/prim/expr.rs
@@ -363,8 +363,6 @@ impl Cast {
     }
 }
 
-// SAFETY: `prim.Cast` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for CastObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Cast => Expr, Cast => PrimExpr);
@@ -453,8 +451,6 @@ impl LShift {
     }
 }
 
-// SAFETY: `prim.LShift` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for LShiftObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(LShift => Expr, LShift => PrimExpr);
@@ -523,8 +519,6 @@ impl RShift {
     }
 }
 
-// SAFETY: `prim.RShift` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for RShiftObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(RShift => Expr, RShift => PrimExpr);
@@ -593,8 +587,6 @@ impl BitwiseAnd {
     }
 }
 
-// SAFETY: `prim.BitwiseAnd` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for BitwiseAndObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(BitwiseAnd => Expr, BitwiseAnd => 
PrimExpr);
@@ -663,8 +655,6 @@ impl BitwiseOr {
     }
 }
 
-// SAFETY: `prim.BitwiseOr` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for BitwiseOrObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(BitwiseOr => Expr, BitwiseOr => PrimExpr);
@@ -733,8 +723,6 @@ impl BitwiseXor {
     }
 }
 
-// SAFETY: `prim.BitwiseXor` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for BitwiseXorObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(BitwiseXor => Expr, BitwiseXor => 
PrimExpr);
@@ -801,8 +789,6 @@ impl BitwiseNot {
     }
 }
 
-// SAFETY: `prim.BitwiseNot` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for BitwiseNotObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(BitwiseNot => Expr, BitwiseNot => 
PrimExpr);
@@ -886,8 +872,6 @@ impl Add {
     }
 }
 
-// SAFETY: `prim.Add` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for AddObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Add => Expr, Add => PrimExpr);
@@ -955,8 +939,6 @@ impl Sub {
     }
 }
 
-// SAFETY: `prim.Sub` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for SubObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Sub => Expr, Sub => PrimExpr);
@@ -1024,8 +1006,6 @@ impl Mul {
     }
 }
 
-// SAFETY: `prim.Mul` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for MulObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Mul => Expr, Mul => PrimExpr);
@@ -1093,8 +1073,6 @@ impl Div {
     }
 }
 
-// SAFETY: `prim.Div` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for DivObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Div => Expr, Div => PrimExpr);
@@ -1162,8 +1140,6 @@ impl Mod {
     }
 }
 
-// SAFETY: `prim.Mod` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for ModObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Mod => Expr, Mod => PrimExpr);
@@ -1231,8 +1207,6 @@ impl FloorDiv {
     }
 }
 
-// SAFETY: `prim.FloorDiv` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for FloorDivObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(FloorDiv => Expr, FloorDiv => PrimExpr);
@@ -1301,8 +1275,6 @@ impl FloorMod {
     }
 }
 
-// SAFETY: `prim.FloorMod` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for FloorModObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(FloorMod => Expr, FloorMod => PrimExpr);
@@ -1371,8 +1343,6 @@ impl Min {
     }
 }
 
-// SAFETY: `prim.Min` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for MinObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Min => Expr, Min => PrimExpr);
@@ -1440,8 +1410,6 @@ impl Max {
     }
 }
 
-// SAFETY: `prim.Max` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for MaxObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Max => Expr, Max => PrimExpr);
@@ -1512,8 +1480,6 @@ impl EQ {
     }
 }
 
-// SAFETY: `prim.EQ` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for EQObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(EQ => Expr, EQ => PrimExpr);
@@ -1582,8 +1548,6 @@ impl NE {
     }
 }
 
-// SAFETY: `prim.NE` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for NEObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(NE => Expr, NE => PrimExpr);
@@ -1652,8 +1616,6 @@ impl LT {
     }
 }
 
-// SAFETY: `prim.LT` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for LTObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(LT => Expr, LT => PrimExpr);
@@ -1722,8 +1684,6 @@ impl LE {
     }
 }
 
-// SAFETY: `prim.LE` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for LEObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(LE => Expr, LE => PrimExpr);
@@ -1792,8 +1752,6 @@ impl GT {
     }
 }
 
-// SAFETY: `prim.GT` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for GTObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(GT => Expr, GT => PrimExpr);
@@ -1862,8 +1820,6 @@ impl GE {
     }
 }
 
-// SAFETY: `prim.GE` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for GEObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(GE => Expr, GE => PrimExpr);
@@ -1935,8 +1891,6 @@ impl And {
     }
 }
 
-// SAFETY: `prim.And` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for AndObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(And => Expr, And => PrimExpr);
@@ -2017,8 +1971,6 @@ impl Or {
     }
 }
 
-// SAFETY: `prim.Or` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for OrObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Or => Expr, Or => PrimExpr);
@@ -2097,8 +2049,6 @@ impl Not {
     }
 }
 
-// SAFETY: `prim.Not` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for NotObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Not => Expr, Not => PrimExpr);
@@ -2195,8 +2145,6 @@ impl Select {
     }
 }
 
-// SAFETY: `prim.Select` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for SelectObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Select => Expr, Select => PrimExpr);
@@ -2324,8 +2272,6 @@ impl Let {
     }
 }
 
-// SAFETY: `prim.Let` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for LetObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Let => Expr, Let => PrimExpr);
diff --git a/rust/src/ir/prim/vector_expr.rs b/rust/src/ir/prim/vector_expr.rs
index 10c6c4088..8d3e5dd96 100644
--- a/rust/src/ir/prim/vector_expr.rs
+++ b/rust/src/ir/prim/vector_expr.rs
@@ -175,8 +175,6 @@ impl Ramp {
     }
 }
 
-// SAFETY: `prim.Ramp` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for RampObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Ramp => Expr, Ramp => PrimExpr);
@@ -289,8 +287,6 @@ impl Broadcast {
     }
 }
 
-// SAFETY: `prim.Broadcast` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for BroadcastObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Broadcast => Expr, Broadcast => PrimExpr);
@@ -381,8 +377,6 @@ impl Shuffle {
     }
 }
 
-// SAFETY: `prim.Shuffle` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for ShuffleObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Shuffle => Expr, Shuffle => PrimExpr);
diff --git a/rust/src/ir/stmt.rs b/rust/src/ir/stmt.rs
index 34101612c..d500e68e8 100644
--- a/rust/src/ir/stmt.rs
+++ b/rust/src/ir/stmt.rs
@@ -189,8 +189,6 @@ unsafe impl UnsafeInit for StmtObj {
     }
 }
 
-// SAFETY: `ir.Stmt` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for StmtObj {}
 // tvm-ffi-stubgen(end)
 
@@ -250,8 +248,6 @@ impl Bind {
     }
 }
 
-// SAFETY: `ir.Bind` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for BindObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Bind => Stmt);
@@ -347,8 +343,6 @@ impl AssertStmt {
     }
 }
 
-// SAFETY: `ir.AssertStmt` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for AssertStmtObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(AssertStmt => Stmt);
@@ -467,8 +461,6 @@ impl For {
     }
 }
 
-// SAFETY: `ir.For` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for ForObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(For => Stmt);
@@ -649,8 +641,6 @@ impl While {
     }
 }
 
-// SAFETY: `ir.While` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for WhileObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(While => Stmt);
@@ -742,8 +732,6 @@ impl TensorStore {
     }
 }
 
-// SAFETY: `ir.TensorStore` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for TensorStoreObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(TensorStore => Stmt);
@@ -869,8 +857,6 @@ impl RegionStmt {
     }
 }
 
-// SAFETY: `ir.RegionStmt` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for RegionStmtObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(RegionStmt => Stmt);
@@ -1032,8 +1018,6 @@ impl SeqStmt {
     }
 }
 
-// SAFETY: `ir.SeqStmt` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for SeqStmtObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(SeqStmt => Stmt);
@@ -1147,8 +1131,6 @@ impl If {
     }
 }
 
-// SAFETY: `ir.If` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for IfObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(If => Stmt);
@@ -1221,8 +1203,6 @@ impl Evaluate {
     }
 }
 
-// SAFETY: `ir.Evaluate` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for EvaluateObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Evaluate => Stmt);
@@ -1285,8 +1265,6 @@ impl Break {
     }
 }
 
-// SAFETY: `ir.Break` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for BreakObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Break => Stmt);
@@ -1345,8 +1323,6 @@ impl Return {
     }
 }
 
-// SAFETY: `ir.Return` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for ReturnObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Return => Stmt);
@@ -1409,8 +1385,6 @@ impl Continue {
     }
 }
 
-// SAFETY: `ir.Continue` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for ContinueObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Continue => Stmt);
diff --git a/rust/src/ir/transform/core.rs b/rust/src/ir/transform/core.rs
index dce5543af..f914d94da 100644
--- a/rust/src/ir/transform/core.rs
+++ b/rust/src/ir/transform/core.rs
@@ -151,8 +151,6 @@ impl PassInfo {
     }
 }
 
-// SAFETY: `transform.PassInfo` is not `_type_mutable`: a shared instance is 
never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for PassInfoObj {}
 // tvm-ffi-stubgen(end)
 
@@ -195,8 +193,6 @@ impl ModulePassObj {
     }
 }
 
-// SAFETY: `transform.ModulePass` is not `_type_mutable`: a shared instance is 
never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for ModulePassObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(ModulePass => Pass);
@@ -264,8 +260,6 @@ impl SequentialObj {
     }
 }
 
-// SAFETY: `transform.Sequential` is not `_type_mutable`: a shared instance is 
never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for SequentialObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Sequential => Pass);
@@ -495,8 +489,6 @@ impl PassInstrumentObj {
     }
 }
 
-// SAFETY: `transform.PassInstrument` is not `_type_mutable`: a shared 
instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for PassInstrumentObj {}
 // tvm-ffi-stubgen(end)
 
diff --git a/rust/src/ir/type.rs b/rust/src/ir/type.rs
index 7818dfcd5..9d2884fba 100644
--- a/rust/src/ir/type.rs
+++ b/rust/src/ir/type.rs
@@ -138,8 +138,6 @@ unsafe impl UnsafeInit for TypeObj {
     }
 }
 
-// SAFETY: `ir.Type` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for TypeObj {}
 // tvm-ffi-stubgen(end)
 
@@ -193,8 +191,6 @@ impl MissingType {
     }
 }
 
-// SAFETY: `ir.MissingType` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for MissingTypeObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(MissingType => Type);
@@ -263,8 +259,6 @@ impl NoneType {
     }
 }
 
-// SAFETY: `ir.NoneType` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for NoneTypeObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(NoneType => Type);
@@ -332,8 +326,6 @@ impl AnyType {
     }
 }
 
-// SAFETY: `ir.AnyType` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for AnyTypeObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(AnyType => Type);
@@ -391,8 +383,6 @@ impl TensorRegionType {
     }
 }
 
-// SAFETY: `ir.TensorRegionType` is not `_type_mutable`: a shared instance is 
never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for TensorRegionTypeObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(TensorRegionType => Type);
@@ -461,8 +451,6 @@ impl OpaqueType {
     }
 }
 
-// SAFETY: `ir.OpaqueType` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for OpaqueTypeObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(OpaqueType => Type);
@@ -522,8 +510,6 @@ impl PrimType {
     }
 }
 
-// SAFETY: `ir.PrimType` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for PrimTypeObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(PrimType => Type);
@@ -666,8 +652,6 @@ impl StringType {
     }
 }
 
-// SAFETY: `ir.StringType` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for StringTypeObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(StringType => Type);
@@ -732,8 +716,6 @@ impl PtrType {
     }
 }
 
-// SAFETY: `ir.PtrType` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for PtrTypeObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(PtrType => Type);
@@ -808,8 +790,6 @@ impl TupleType {
     }
 }
 
-// SAFETY: `ir.TupleType` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for TupleTypeObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(TupleType => Type);
@@ -883,8 +863,6 @@ impl FuncType {
     }
 }
 
-// SAFETY: `ir.FuncType` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for FuncTypeObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(FuncType => Type);
diff --git a/rust/src/runtime.rs b/rust/src/runtime.rs
index b5aada2ac..7c3738636 100644
--- a/rust/src/runtime.rs
+++ b/rust/src/runtime.rs
@@ -95,8 +95,6 @@ impl Deref for MemoryScope {
     }
 }
 
-// SAFETY: `runtime.MemoryScope` is not `_type_mutable`: a shared instance is 
never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for MemoryScopeObj {}
 // tvm-ffi-stubgen(end)
 
diff --git a/rust/src/sym/analyzer.rs b/rust/src/sym/analyzer.rs
index 9eaa63f82..6f44c6fde 100644
--- a/rust/src/sym/analyzer.rs
+++ b/rust/src/sym/analyzer.rs
@@ -441,8 +441,6 @@ impl ConstIntBound {
     }
 }
 
-// SAFETY: `sym.ConstIntBound` is not `_type_mutable`: a shared instance is 
never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for ConstIntBoundObj {}
 // tvm-ffi-stubgen(end)
 
@@ -491,8 +489,6 @@ impl ModularSet {
     }
 }
 
-// SAFETY: `sym.ModularSet` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for ModularSetObj {}
 // tvm-ffi-stubgen(end)
 
@@ -574,8 +570,6 @@ impl RewriteSimplifierStats {
     }
 }
 
-// SAFETY: `sym.RewriteSimplifierStats` is not `_type_mutable`: a shared 
instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for RewriteSimplifierStatsObj {}
 // tvm-ffi-stubgen(end)
 
diff --git a/rust/src/sym/constraint.rs b/rust/src/sym/constraint.rs
index dbc482c53..d69637d49 100644
--- a/rust/src/sym/constraint.rs
+++ b/rust/src/sym/constraint.rs
@@ -122,8 +122,6 @@ unsafe impl UnsafeInit for ConstraintObj {
     }
 }
 
-// SAFETY: `sym.Constraint` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for ConstraintObj {}
 // tvm-ffi-stubgen(end)
 
@@ -179,8 +177,6 @@ impl BindingConstraint {
     }
 }
 
-// SAFETY: `sym.BindingConstraint` is not `_type_mutable`: a shared instance 
is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for BindingConstraintObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(BindingConstraint => Constraint);
@@ -238,8 +234,6 @@ impl PredicateConstraint {
     }
 }
 
-// SAFETY: `sym.PredicateConstraint` is not `_type_mutable`: a shared instance 
is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for PredicateConstraintObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(PredicateConstraint => Constraint);
@@ -297,8 +291,6 @@ impl RangeConstraint {
     }
 }
 
-// SAFETY: `sym.RangeConstraint` is not `_type_mutable`: a shared instance is 
never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for RangeConstraintObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(RangeConstraint => Constraint);
diff --git a/rust/src/sym/int_set.rs b/rust/src/sym/int_set.rs
index c0ed0f2ba..37de5508d 100644
--- a/rust/src/sym/int_set.rs
+++ b/rust/src/sym/int_set.rs
@@ -163,8 +163,6 @@ impl IntervalSetObj {
     }
 }
 
-// SAFETY: `sym.IntervalSet` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for IntervalSetObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(IntervalSet => IntSet);
diff --git a/rust/src/sym/iter_affine_map.rs b/rust/src/sym/iter_affine_map.rs
index b9ef5ca39..b85703838 100644
--- a/rust/src/sym/iter_affine_map.rs
+++ b/rust/src/sym/iter_affine_map.rs
@@ -225,8 +225,6 @@ impl IterMark {
     }
 }
 
-// SAFETY: `sym.IterMark` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for IterMarkObj {}
 // tvm-ffi-stubgen(end)
 
@@ -278,8 +276,6 @@ impl IterSplitExprObj {
     }
 }
 
-// SAFETY: `sym.IterSplitExpr` is not `_type_mutable`: a shared instance is 
never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for IterSplitExprObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(IterSplitExpr => Expr, IterSplitExpr => 
IterMapExpr, IterSplitExpr => PrimExpr);
@@ -325,8 +321,6 @@ impl IterSumExprObj {
     }
 }
 
-// SAFETY: `sym.IterSumExpr` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for IterSumExprObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(IterSumExpr => Expr, IterSumExpr => 
IterMapExpr, IterSumExpr => PrimExpr);
diff --git a/rust/src/tirx/function.rs b/rust/src/tirx/function.rs
index b57671869..0d7c8948c 100644
--- a/rust/src/tirx/function.rs
+++ b/rust/src/tirx/function.rs
@@ -148,8 +148,6 @@ impl Function {
     }
 }
 
-// SAFETY: `tirx.Function` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for FunctionObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(Function => Expr, Function => BaseFunc);
diff --git a/rust/src/tirx/index_map.rs b/rust/src/tirx/index_map.rs
index 6fe599159..13c49bc85 100644
--- a/rust/src/tirx/index_map.rs
+++ b/rust/src/tirx/index_map.rs
@@ -129,8 +129,6 @@ impl IndexMap {
     }
 }
 
-// SAFETY: `tirx.IndexMap` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for IndexMapObj {}
 // tvm-ffi-stubgen(end)
 
diff --git a/rust/src/tirx/layout.rs b/rust/src/tirx/layout.rs
index 4147dfbfb..14a8d3c91 100644
--- a/rust/src/tirx/layout.rs
+++ b/rust/src/tirx/layout.rs
@@ -261,8 +261,6 @@ impl TileLayoutObj {
     }
 }
 
-// SAFETY: `tirx.TileLayout` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for TileLayoutObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(TileLayout => Layout);
@@ -381,8 +379,6 @@ impl Iter {
     }
 }
 
-// SAFETY: `tirx.Iter` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for IterObj {}
 // tvm-ffi-stubgen(end)
 
@@ -411,8 +407,6 @@ impl Deref for Axis {
     }
 }
 
-// SAFETY: `tirx.Axis` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for AxisObj {}
 // tvm-ffi-stubgen(end)
 
@@ -510,8 +504,6 @@ impl ComposeLayoutObj {
     }
 }
 
-// SAFETY: `tirx.ComposeLayout` is not `_type_mutable`: a shared instance is 
never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for ComposeLayoutObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(ComposeLayout => Layout);
diff --git a/rust/src/tirx/op.rs b/rust/src/tirx/op.rs
index ac7bb8c6b..a59275c7b 100644
--- a/rust/src/tirx/op.rs
+++ b/rust/src/tirx/op.rs
@@ -169,8 +169,6 @@ impl CallFFIKernelAttr {
     }
 }
 
-// SAFETY: `tirx.CallFFIKernelAttr` is not `_type_mutable`: a shared instance 
is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for CallFFIKernelAttrObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(CallFFIKernelAttr => Attrs);
diff --git a/rust/src/tirx/tensor.rs b/rust/src/tirx/tensor.rs
index 278bd697b..27da0d86a 100644
--- a/rust/src/tirx/tensor.rs
+++ b/rust/src/tirx/tensor.rs
@@ -165,8 +165,6 @@ impl TensorType {
     }
 }
 
-// SAFETY: `tirx.TensorType` is not `_type_mutable`: a shared instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for TensorTypeObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(TensorType => Type);
diff --git a/rust/src/tirx/thread_scope.rs b/rust/src/tirx/thread_scope.rs
index 761b55dbb..c450045dd 100644
--- a/rust/src/tirx/thread_scope.rs
+++ b/rust/src/tirx/thread_scope.rs
@@ -84,8 +84,6 @@ impl Deref for ThreadScope {
     }
 }
 
-// SAFETY: `tirx.ThreadScope` is not `_type_mutable`: a shared instance is 
never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for ThreadScopeObj {}
 // tvm-ffi-stubgen(end)
 
diff --git a/rust/src/tirx/tile/dispatch.rs b/rust/src/tirx/tile/dispatch.rs
index 25eb54ed4..12d1273c2 100644
--- a/rust/src/tirx/tile/dispatch.rs
+++ b/rust/src/tirx/tile/dispatch.rs
@@ -149,8 +149,6 @@ impl DispatchContextObj {
     }
 }
 
-// SAFETY: `tirx.DispatchContext` is not `_type_mutable`: a shared instance is 
never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for DispatchContextObj {}
 // tvm-ffi-stubgen(end)
 
diff --git a/rust/src/tirx/tile/instruction.rs 
b/rust/src/tirx/tile/instruction.rs
index aece34084..6a8e08291 100644
--- a/rust/src/tirx/tile/instruction.rs
+++ b/rust/src/tirx/tile/instruction.rs
@@ -105,8 +105,6 @@ impl ScopeAttrs {
     }
 }
 
-// SAFETY: `tirx.tensor.ScopeAttrs` is not `_type_mutable`: a shared instance 
is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for ScopeAttrsObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(ScopeAttrs => Attrs);
@@ -201,8 +199,6 @@ impl TrnAttrs {
     }
 }
 
-// SAFETY: `tirx.tensor.TrnAttrs` is not `_type_mutable`: a shared instance is 
never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for TrnAttrsObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(TrnAttrs => Attrs);
diff --git a/rust/src/tirx/transform/function_pass.rs 
b/rust/src/tirx/transform/function_pass.rs
index 8fd6701b8..db03f802d 100644
--- a/rust/src/tirx/transform/function_pass.rs
+++ b/rust/src/tirx/transform/function_pass.rs
@@ -106,8 +106,6 @@ impl FunctionPassObj {
     }
 }
 
-// SAFETY: `tirx.FunctionPass` is not `_type_mutable`: a shared instance is 
never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for FunctionPassObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(FunctionPass => Pass);
diff --git a/rust/src/tirx/transform/transform.rs 
b/rust/src/tirx/transform/transform.rs
index f8e74876a..86841f6f2 100644
--- a/rust/src/tirx/transform/transform.rs
+++ b/rust/src/tirx/transform/transform.rs
@@ -107,8 +107,6 @@ impl RemoveNoOpConfig {
     }
 }
 
-// SAFETY: `tirx.transform.RemoveNoOpConfig` is not `_type_mutable`: a shared 
instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for RemoveNoOpConfigObj {}
 // tvm-ffi-stubgen(end)
 
@@ -185,8 +183,6 @@ impl UnrollLoopConfig {
     }
 }
 
-// SAFETY: `tirx.transform.UnrollLoopConfig` is not `_type_mutable`: a shared 
instance is never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for UnrollLoopConfigObj {}
 // tvm-ffi-stubgen(end)
 
diff --git a/rust/src/tirx/type.rs b/rust/src/tirx/type.rs
index 7c0740b79..e0655f82d 100644
--- a/rust/src/tirx/type.rs
+++ b/rust/src/tirx/type.rs
@@ -93,8 +93,6 @@ impl TensorMapType {
     }
 }
 
-// SAFETY: `tirx.TensorMapType` is not `_type_mutable`: a shared instance is 
never
-// mutated, as C++ changes it only through copy-on-write.
 unsafe impl tvm_ffi::object::ImmutableObject for TensorMapTypeObj {}
 
 tvm_ffi::unsafe_impl_object_upcast!(TensorMapType => Type);
diff --git a/src/sym/canonical_simplify.cc b/src/sym/canonical_simplify.cc
index 4bb452f36..d839ac018 100644
--- a/src/sym/canonical_simplify.cc
+++ b/src/sym/canonical_simplify.cc
@@ -617,7 +617,7 @@ class CanonicalSimplifier::Impl : public 
RewriteSimplifier::Impl {
       }
       return expr;
     } catch (ffi::Error& error) {
-      ffi::detail::UpdateVisitErrorContext(error, value);
+      ffi::detail::UpdateVisitErrorContext(&error, value);
       throw;
     }
   }
diff --git a/src/sym/iter_affine_map.cc b/src/sym/iter_affine_map.cc
index 8068407f5..012c1794c 100644
--- a/src/sym/iter_affine_map.cc
+++ b/src/sym/iter_affine_map.cc
@@ -333,7 +333,7 @@ class IterMapRewriter : public tvm::ExprMutator {
       }
       return value;
     } catch (ffi::Error& error) {
-      ffi::detail::UpdateVisitErrorContext(error, input);
+      ffi::detail::UpdateVisitErrorContext(&error, input);
       throw;
     }
   }
diff --git a/src/tirx/ir/stmt_functor_with_constraint_context.cc 
b/src/tirx/ir/stmt_functor_with_constraint_context.cc
index 4f357c9cd..87dbabb61 100644
--- a/src/tirx/ir/stmt_functor_with_constraint_context.cc
+++ b/src/tirx/ir/stmt_functor_with_constraint_context.cc
@@ -94,7 +94,7 @@ ffi::Optional<ffi::VisitInterrupt> 
ObjectVisitorWithConstraintContext::Visit(ffi
       return (*native_vtable_)(value.cast<const ffi::Object*>(), this);
     return DefaultVisitExpected(value).value();
   } catch (ffi::Error& error) {
-    ffi::detail::UpdateVisitErrorContext(error, value);
+    ffi::detail::UpdateVisitErrorContext(&error, value);
     throw;
   }
 }
@@ -109,11 +109,13 @@ ffi::UnchangedOr<ffi::Any> 
ObjectMutatorWithConstraintContext::Mutate(ffi::AnyVi
     } catch (ffi::Error& error) {
       // Default mutation already names the current node. A user override may 
throw
       // before delegating; attach its frame without duplicating default 
descent's frame.
-      auto context = ffi::VisitErrorContext::TryGetFromError(error);
-      if (!context.has_value() || 
context.value()->reverse_visit_pattern.empty() ||
-          context.value()->reverse_visit_pattern.back().get() != object) {
-        ffi::detail::UpdateVisitErrorContext(error, value);
-      }
+      // Release the context handle before the update so a unique context is 
appended in place.
+      bool named = [&] {
+        auto context = ffi::VisitErrorContext::TryGetFromError(error);
+        return context.has_value() && 
!context.value()->reverse_visit_pattern.empty() &&
+               context.value()->reverse_visit_pattern.back().get() == object;
+      }();
+      if (!named) ffi::detail::UpdateVisitErrorContext(&error, value);
       throw;
     }
   }
diff --git a/tests/cpp/ir/expr_functor_test.cc 
b/tests/cpp/ir/expr_functor_test.cc
index dd4edf456..3f3dbc01a 100644
--- a/tests/cpp/ir/expr_functor_test.cc
+++ b/tests/cpp/ir/expr_functor_test.cc
@@ -104,7 +104,9 @@ TEST(ExprMutator, 
NativeErrorContextThroughStructuralFallback) {
   PairExpr pair(sum, IntImm::Int32(3));
   auto result = mutator->MutateExpected(pair);
   ASSERT_TRUE(result.is_err());
-  EXPECT_TRUE(result.error().same_as(mutator->error));
+  // The mutator still holds the thrown Error, so the context lands on a copy.
+  
EXPECT_FALSE(ffi::VisitErrorContext::TryGetFromError(mutator->error).has_value());
+  EXPECT_EQ(result.error().message(), "native mutation error");
   auto context = ffi::VisitErrorContext::TryGetFromError(result.error());
   ASSERT_TRUE(context.has_value());
   const auto& pattern = context.value()->reverse_visit_pattern;
@@ -128,7 +130,8 @@ TEST(ExprFunctor, AttachesContextAndPreservesError) {
     functor(node);
     FAIL() << "Expected a dispatch failure";
   } catch (const ffi::Error& error) {
-    EXPECT_TRUE(error.same_as(functor.error));
+    // The functor still holds the thrown Error, so the context lands on a 
copy.
+    
EXPECT_FALSE(ffi::VisitErrorContext::TryGetFromError(functor.error).has_value());
     EXPECT_EQ(error.kind(), "ValueError");
     EXPECT_EQ(error.message(), "dispatch failure");
     EXPECT_EQ(error.backtrace(), "original backtrace");
diff --git a/tests/cpp/tirx/stmt_functor_with_constraint_context_test.cc 
b/tests/cpp/tirx/stmt_functor_with_constraint_context_test.cc
index 7c8924284..dd7e28fc7 100644
--- a/tests/cpp/tirx/stmt_functor_with_constraint_context_test.cc
+++ b/tests/cpp/tirx/stmt_functor_with_constraint_context_test.cc
@@ -309,7 +309,9 @@ TEST(ConstraintFunctor, NativeVisitorErrorPropagation) {
   PrimExpr root = prim::Add(IntImm::Int32(1), IntImm::Int32(2));
   auto result = visitor->VisitExpected(root);
   ASSERT_TRUE(result.is_err());
-  EXPECT_TRUE(result.error().same_as(visitor->error));
+  // The visitor still holds the thrown Error, so the context lands on a copy.
+  
EXPECT_FALSE(ffi::VisitErrorContext::TryGetFromError(visitor->error).has_value());
+  EXPECT_EQ(result.error().message(), "native visit failure");
   auto context = ffi::VisitErrorContext::TryGetFromError(result.error());
   ASSERT_TRUE(context.has_value());
   ASSERT_EQ(context.value()->reverse_visit_pattern.size(), 2);

Reply via email to