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 26b0e69d4 [Rust] Bump tvm-ffi to latest (#211)
26b0e69d4 is described below
commit 26b0e69d4a7273e45c0faad3701855efc1790978
Author: Tianqi Chen <[email protected]>
AuthorDate: Fri Nov 6 12:00:59 2026 -0500
[Rust] Bump tvm-ffi to latest (#211)
Bump tvm-ffi to latest.
- Adopt its cleanups: drop the repeated-frame check in the
constraint-context mutator (tvm-ffi now skips it), and use
`unsafe_impl_ref_downcast!` in `typed_expr_view!`.
- Fix the Rust clippy findings and run pinned clippy in the lint job
when Rust changes.
---
.github/workflows/lint.yml | 19 ++++++++++++++
3rdparty/tvm-ffi | 2 +-
rust/src/backend/cuda/op.rs | 2 ++
rust/src/ir/attrs.rs | 2 ++
rust/src/ir/global_info.rs | 2 ++
rust/src/ir/location.rs | 3 +++
rust/src/ir/prim/op.rs | 2 +-
rust/src/ir/stmt.rs | 4 ++-
rust/src/ir/type.rs | 6 +++++
rust/src/macro/def_expr_op_overloads.rs | 2 ++
rust/src/macro/typed_expr_view.rs | 29 +++-------------------
rust/src/sym/analyzer.rs | 2 ++
rust/src/sym/constraint.rs | 4 ++-
rust/src/tirx/tile/dispatch.rs | 6 +----
rust/src/tirx/tile/instruction.rs | 2 ++
rust/tests/sym/iter_affine_map.rs | 2 +-
.../ir/stmt_functor_with_constraint_context.cc | 12 +++------
17 files changed, 56 insertions(+), 45 deletions(-)
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 8ac5f2f9f..5b0a0c19d 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -39,3 +39,22 @@ jobs:
fetch-depth: 0
fetch-tags: true
- uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd #
v3.0.1
+ - name: Detect Rust changes
+ id: rust_changes
+ run: |
+ # The crate builds against the submodule by path, so a bump counts.
+ if [ "${{ github.event_name }}" != "pull_request" ] ||
+ ! git diff --quiet "${{ github.event.pull_request.base.sha }}"
HEAD -- \
+ rust/ 3rdparty/tvm-ffi .github/workflows/lint.yml; then
+ echo "changed=true" >> "$GITHUB_OUTPUT"
+ fi
+ # Clippy only type-checks, so DOCS_RS skips the tvm-ffi-config lookup and
+ # no build is needed. Pin it so new lints arrive with a toolchain bump.
+ - name: Rust clippy
+ if: steps.rust_changes.outputs.changed == 'true'
+ env:
+ DOCS_RS: "1"
+ run: |
+ git submodule update --init 3rdparty/tvm-ffi
+ rustup toolchain install 1.99.1 --profile minimal --component clippy
+ cargo +1.99.1 clippy --manifest-path rust/Cargo.toml --all-targets
-- -D warnings
diff --git a/3rdparty/tvm-ffi b/3rdparty/tvm-ffi
index 9288282fe..a472db8d8 160000
--- a/3rdparty/tvm-ffi
+++ b/3rdparty/tvm-ffi
@@ -1 +1 @@
-Subproject commit 9288282fee38e0ba681411b80bb36d211d436e60
+Subproject commit a472db8d80b57c6d6be34965e84133f7ce450c57
diff --git a/rust/src/backend/cuda/op.rs b/rust/src/backend/cuda/op.rs
index 269959368..46a2a5bbc 100644
--- a/rust/src/backend/cuda/op.rs
+++ b/rust/src/backend/cuda/op.rs
@@ -18,6 +18,8 @@
*/
// The reflected field names `M`, `N`, and `K` are kept as they are.
#![allow(dead_code, unused_imports, non_snake_case)]
+// The generated constructors take one argument per reflected field.
+#![allow(clippy::too_many_arguments)]
//! The attributes of CUDA instructions.
//!
diff --git a/rust/src/ir/attrs.rs b/rust/src/ir/attrs.rs
index 80a841534..006eadefa 100644
--- a/rust/src/ir/attrs.rs
+++ b/rust/src/ir/attrs.rs
@@ -17,6 +17,8 @@
* under the License.
*/
#![allow(dead_code, unused_imports)]
+// The generated `new` of a field-less base needs no `Default`.
+#![allow(clippy::new_without_default)]
//! Attributes attached to calls, functions and modules.
//!
diff --git a/rust/src/ir/global_info.rs b/rust/src/ir/global_info.rs
index 6ddebd1f2..9f699d843 100644
--- a/rust/src/ir/global_info.rs
+++ b/rust/src/ir/global_info.rs
@@ -17,6 +17,8 @@
* under the License.
*/
#![allow(dead_code, unused_imports)]
+// The generated `new` of a field-less base needs no `Default`.
+#![allow(clippy::new_without_default)]
//! Module-level information that is not a function.
//!
diff --git a/rust/src/ir/location.rs b/rust/src/ir/location.rs
index 1faeb66fc..ad29b147c 100644
--- a/rust/src/ir/location.rs
+++ b/rust/src/ir/location.rs
@@ -17,6 +17,9 @@
* under the License.
*/
#![allow(dead_code, unused_imports)]
+// The generated `new` of a field-less base needs no `Default`, and
`UnknownLoc::new` fetches a
+// shared FFI singleton.
+#![allow(clippy::new_without_default)]
//! Source locations of IR nodes, for diagnostics.
//!
diff --git a/rust/src/ir/prim/op.rs b/rust/src/ir/prim/op.rs
index e4e6d7e10..f0431cabd 100644
--- a/rust/src/ir/prim/op.rs
+++ b/rust/src/ir/prim/op.rs
@@ -296,7 +296,7 @@ fn binary(
) -> ExprResult {
let rhs = typed_after(rhs.classify(), &lhs);
match (lhs.0, rhs.0) {
- (Ok(a), Ok(b)) => ExprResult(op(a.into(), b.into())),
+ (Ok(a), Ok(b)) => ExprResult(op(a, b)),
(Err(error), _) | (_, Err(error)) => ExprResult(Err(error)),
}
}
diff --git a/rust/src/ir/stmt.rs b/rust/src/ir/stmt.rs
index d500e68e8..72515fdc0 100644
--- a/rust/src/ir/stmt.rs
+++ b/rust/src/ir/stmt.rs
@@ -17,6 +17,8 @@
* under the License.
*/
#![allow(dead_code, unused_imports)]
+// The generated constructors take one argument per reflected field.
+#![allow(clippy::too_many_arguments)]
//! Statements: bindings, assertions, loops, conditionals, tensor stores and
sequences.
//!
@@ -1036,7 +1038,7 @@ impl SeqStmt {
fn flatten(seq: Array<Stmt>) -> Array<Stmt> {
let nested_or_no_op =
|stmt: &Stmt| stmt.downcast_ref::<SeqStmtObj>().is_some() ||
is_no_op(stmt);
- if !seq.iter().any(|stmt| nested_or_no_op(&stmt)) {
+ if !seq.iter().any(nested_or_no_op) {
return seq;
}
fn append(stmt: Stmt, flattened: &mut Vec<Stmt>) {
diff --git a/rust/src/ir/type.rs b/rust/src/ir/type.rs
index 9d2884fba..95ce36ca7 100644
--- a/rust/src/ir/type.rs
+++ b/rust/src/ir/type.rs
@@ -199,6 +199,8 @@ tvm_ffi::unsafe_impl_object_upcast!(MissingType => Type);
impl MissingType {
/// Return the shared type of a node whose type is not known yet, fetched
once per thread
/// (`ir.MissingType`).
+ // Not `Default`: `new` fetches a shared FFI singleton rather than
building a value.
+ #[allow(clippy::new_without_default)]
pub fn new() -> Self {
thread_local! {
static MISSING_TYPE: std::cell::OnceCell<MissingType> = const {
std::cell::OnceCell::new() };
@@ -266,6 +268,8 @@ tvm_ffi::unsafe_impl_object_upcast!(NoneType => Type);
impl NoneType {
/// Return the shared type of the `None` value, fetched once per thread
(`ir.NoneType`).
+ // Not `Default`: `new` fetches a shared FFI singleton rather than
building a value.
+ #[allow(clippy::new_without_default)]
pub fn new() -> Self {
thread_local! {
static NONE_TYPE: std::cell::OnceCell<NoneType> = const {
std::cell::OnceCell::new() };
@@ -390,6 +394,8 @@ tvm_ffi::unsafe_impl_object_upcast!(TensorRegionType =>
Type);
impl TensorRegionType {
/// Return the shared type of a tensor region, fetched once per thread
(`ir.TensorRegionType`).
+ // Not `Default`: `new` fetches a shared FFI singleton rather than
building a value.
+ #[allow(clippy::new_without_default)]
pub fn new() -> Self {
thread_local! {
static TENSOR_REGION_TYPE: std::cell::OnceCell<TensorRegionType> =
diff --git a/rust/src/macro/def_expr_op_overloads.rs
b/rust/src/macro/def_expr_op_overloads.rs
index 2013f3c9c..e2332b1c3 100644
--- a/rust/src/macro/def_expr_op_overloads.rs
+++ b/rust/src/macro/def_expr_op_overloads.rs
@@ -60,6 +60,8 @@
/// # Ok(())
/// # }
/// ```
+// `crate::` matches the caller's path and re-emits it, so it names the
caller's crate.
+#[allow(clippy::crate_in_macro_def)]
#[macro_export]
macro_rules! def_expr_op_over_loads {
(crate::$($ty:ident)::+ $(,)?) => {
diff --git a/rust/src/macro/typed_expr_view.rs
b/rust/src/macro/typed_expr_view.rs
index 52d8c70f4..8d6bd490a 100644
--- a/rust/src/macro/typed_expr_view.rs
+++ b/rust/src/macro/typed_expr_view.rs
@@ -113,32 +113,9 @@ macro_rules! typed_expr_view {
}
}
- // As `#[derive(ObjectRef)]` generates: the view is exactly one object
pointer, so a
- // cell or an object pointer that holds a `$name` borrows as `&$name`
in place.
- // SAFETY: the view is `repr(transparent)` over its `ObjectArc`, and
the checked
- // forms run `check_any_strict` first.
- unsafe impl tvm_ffi::type_traits::RefFromAnyUnchecked for $name {
- #[inline(always)]
- unsafe fn ref_from_any_unchecked(cell: &TVMFFIAny) -> &Self {
- unsafe { &*(::core::ptr::addr_of!(cell.data_union) as *const
Self) }
- }
- }
-
- unsafe impl tvm_ffi::type_traits::DowncastRefFromAny for $name {
- #[inline(always)]
- unsafe fn downcast_ref_from_any(cell: &TVMFFIAny) -> Option<&Self>
{
- unsafe {
tvm_ffi::type_traits::downcast_ref_from_any_in_place::<Self>(cell) }
- }
- }
-
- unsafe impl tvm_ffi::type_traits::DowncastRefFromObject for $name {
- #[inline(always)]
- unsafe fn downcast_ref_from_object(
- place: &*mut tvm_ffi::tvm_ffi_sys::TVMFFIObject,
- ) -> Option<&Self> {
- unsafe {
tvm_ffi::type_traits::downcast_ref_from_object_in_place::<Self>(place) }
- }
- }
+ // SAFETY: the view is `repr(transparent)` over one object pointer, and
+ // `check_any_strict` is its type check.
+ tvm_ffi::unsafe_impl_ref_downcast!($name);
impl AsRef<$name> for $name {
#[inline(always)]
diff --git a/rust/src/sym/analyzer.rs b/rust/src/sym/analyzer.rs
index 6f44c6fde..dd11e007c 100644
--- a/rust/src/sym/analyzer.rs
+++ b/rust/src/sym/analyzer.rs
@@ -122,6 +122,8 @@ impl Deref for Analyzer {
impl Analyzer {
/// Create an analyzer that knows no facts (`sym.Analyzer`).
+ // Not `Default`: creating an analyzer allocates a stateful FFI object.
+ #[allow(clippy::new_without_default)]
pub fn new() -> Self {
support::infallible(
tvm_ffi::cached_global_func!("sym.Analyzer")
diff --git a/rust/src/sym/constraint.rs b/rust/src/sym/constraint.rs
index d69637d49..630719bcb 100644
--- a/rust/src/sym/constraint.rs
+++ b/rust/src/sym/constraint.rs
@@ -17,6 +17,8 @@
* under the License.
*/
#![allow(dead_code, unused_imports)]
+// The generated `new` of a field-less base needs no `Default`.
+#![allow(clippy::new_without_default)]
//! Constraints: the facts in scope at a point of a traversal.
//!
@@ -412,7 +414,7 @@ impl ConstraintContextObj {
parent.for_each_prefix(self.parent_prefix_size, callback);
}
for constraint in local.iter().take(prefix as usize) {
- callback(&constraint);
+ callback(constraint);
}
}
diff --git a/rust/src/tirx/tile/dispatch.rs b/rust/src/tirx/tile/dispatch.rs
index 12d1273c2..ab937439b 100644
--- a/rust/src/tirx/tile/dispatch.rs
+++ b/rust/src/tirx/tile/dispatch.rs
@@ -257,11 +257,7 @@ impl DispatchContext {
}
/// Cache `value` under `key` across dispatches
(`tirx.DispatchContextSharedStateSet`).
- pub fn cache_set(
- &self,
- key: &str,
- value: &(impl ObjectRefCore + tvm_ffi::type_traits::AnyCompatible),
- ) -> Result<()> {
+ pub fn cache_set(&self, key: &str, value: &impl ObjectRefCore) ->
Result<()> {
let key = String::from(key);
tvm_ffi::cached_global_func!("tirx.DispatchContextSharedStateSet").call_packed(&[
AnyView::from(self),
diff --git a/rust/src/tirx/tile/instruction.rs
b/rust/src/tirx/tile/instruction.rs
index 6a8e08291..ae7ebf875 100644
--- a/rust/src/tirx/tile/instruction.rs
+++ b/rust/src/tirx/tile/instruction.rs
@@ -17,6 +17,8 @@
* under the License.
*/
#![allow(dead_code, unused_imports)]
+// The generated constructors take one argument per reflected field.
+#![allow(clippy::too_many_arguments)]
//! The attributes of tile instruction calls.
//!
diff --git a/rust/tests/sym/iter_affine_map.rs
b/rust/tests/sym/iter_affine_map.rs
index 8b8ca0b26..fbd42f2d3 100644
--- a/rust/tests/sym/iter_affine_map.rs
+++ b/rust/tests/sym/iter_affine_map.rs
@@ -73,7 +73,7 @@ fn iter_maps_decompose_into_marks_and_splits() {
let mut lower_factors = Vec::new();
for sum in result.indices.iter() {
assert_eq!(as_int(sum.base_().unwrap()), 0);
- let outer = only_split(&sum);
+ let outer = only_split(sum);
let mark: IterMark = outer.source().unwrap();
assert_eq!(as_int(mark.extent.clone()), 4);
let inner_sum: IterSumExpr = mark.source.clone().downcast().unwrap();
diff --git a/src/tirx/ir/stmt_functor_with_constraint_context.cc
b/src/tirx/ir/stmt_functor_with_constraint_context.cc
index 87dbabb61..1da42574d 100644
--- a/src/tirx/ir/stmt_functor_with_constraint_context.cc
+++ b/src/tirx/ir/stmt_functor_with_constraint_context.cc
@@ -107,15 +107,9 @@ ffi::UnchangedOr<ffi::Any>
ObjectMutatorWithConstraintContext::Mutate(ffi::AnyVi
try {
return (*native_vtable_)(object, this, mode);
} 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.
- // 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);
+ // A user override may throw before delegating; the update skips a frame
that
+ // default descent already reported.
+ ffi::detail::UpdateVisitErrorContext(&error, value);
throw;
}
}