[Mlir-commits] [mlir] [MLIR][Python] Remove partial LLVM APIs in python bindings (2/n) (PR #178529)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Thu Jan 29 08:57:17 PST 2026


https://github.com/RattataKing updated https://github.com/llvm/llvm-project/pull/178529

>From 6a8754cd2d7720ca76cd9c8b4754cff113013dad Mon Sep 17 00:00:00 2001
From: Amily Wu <amilywu2 at amd.com>
Date: Wed, 28 Jan 2026 22:05:46 +0000
Subject: [PATCH 1/6] Clean llvm enum and zip

---
 mlir/lib/Bindings/Python/IRCore.cpp | 67 +++++++++++++++--------------
 1 file changed, 34 insertions(+), 33 deletions(-)

diff --git a/mlir/lib/Bindings/Python/IRCore.cpp b/mlir/lib/Bindings/Python/IRCore.cpp
index 7a344c1214c1c..8fe5f855ef450 100644
--- a/mlir/lib/Bindings/Python/IRCore.cpp
+++ b/mlir/lib/Bindings/Python/IRCore.cpp
@@ -1476,16 +1476,18 @@ static void populateResultTypes(std::string_view name, nb::list resultTypeList,
   resultTypes.reserve(resultTypeList.size());
   if (resultSegmentSpecObj.is_none()) {
     // Non-variadic result unpacking.
-    for (const auto &it : llvm::enumerate(resultTypeList)) {
+    size_t index = 0;
+    for (const auto &resultType : resultTypeList) {
       try {
-        resultTypes.push_back(nb::cast<PyType *>(it.value()));
+        resultTypes.push_back(nb::cast<PyType *>(resultType));
         if (!resultTypes.back())
           throw nb::cast_error();
       } catch (nb::cast_error &err) {
-        throw nb::value_error(join("Result ", it.index(), " of operation \"",
-                                   name, "\" must be a Type (", err.what(), ")")
+        throw nb::value_error(join("Result ", index, " of operation \"", name,
+                                   "\" must be a Type (", err.what(), ")")
                                   .c_str());
       }
+      ++index;
     }
   } else {
     // Sized result unpacking.
@@ -1497,13 +1499,13 @@ static void populateResultTypes(std::string_view name, nb::list resultTypeList,
               .c_str());
     }
     resultSegmentLengths.reserve(resultTypeList.size());
-    for (const auto &it :
-         llvm::enumerate(llvm::zip(resultTypeList, resultSegmentSpec))) {
-      int segmentSpec = std::get<1>(it.value());
+    size_t size = resultSegmentSpec.size();
+    for (size_t index = 0; index < size; ++index) {
+      int segmentSpec = resultSegmentSpec[index];
       if (segmentSpec == 1 || segmentSpec == 0) {
         // Unpack unary element.
         try {
-          auto *resultType = nb::cast<PyType *>(std::get<0>(it.value()));
+          auto *resultType = nb::cast<PyType *>(resultTypeList[index]);
           if (resultType) {
             resultTypes.push_back(resultType);
             resultSegmentLengths.push_back(1);
@@ -1512,25 +1514,24 @@ static void populateResultTypes(std::string_view name, nb::list resultTypeList,
             resultSegmentLengths.push_back(0);
           } else {
             throw nb::value_error(
-                join("Result ", it.index(), " of operation \"", name,
+                join("Result ", index, " of operation \"", name,
                      "\" must be a Type (was None and result is not optional)")
                     .c_str());
           }
         } catch (nb::cast_error &err) {
-          throw nb::value_error(join("Result ", it.index(), " of operation \"",
-                                     name, "\" must be a Type (", err.what(),
-                                     ")")
+          throw nb::value_error(join("Result ", index, " of operation \"", name,
+                                     "\" must be a Type (", err.what(), ")")
                                     .c_str());
         }
       } else if (segmentSpec == -1) {
         // Unpack sequence by appending.
         try {
-          if (std::get<0>(it.value()).is_none()) {
+          if (resultTypeList[index].is_none()) {
             // Treat it as an empty list.
             resultSegmentLengths.push_back(0);
           } else {
             // Unpack the list.
-            auto segment = nb::cast<nb::sequence>(std::get<0>(it.value()));
+            auto segment = nb::cast<nb::sequence>(resultTypeList[index]);
             for (nb::handle segmentItem : segment) {
               resultTypes.push_back(nb::cast<PyType *>(segmentItem));
               if (!resultTypes.back()) {
@@ -1543,8 +1544,8 @@ static void populateResultTypes(std::string_view name, nb::list resultTypeList,
           // NOTE: Sloppy to be using a catch-all here, but there are at least
           // three different unrelated exceptions that can be thrown in the
           // above "casts". Just keep the scope above small and catch them all.
-          throw nb::value_error(join("Result ", it.index(), " of operation \"",
-                                     name, "\" must be a Sequence of Types (",
+          throw nb::value_error(join("Result ", index, " of operation \"", name,
+                                     "\" must be a Sequence of Types (",
                                      err.what(), ")")
                                     .c_str());
         }
@@ -1637,17 +1638,18 @@ nb::object PyOpView::buildGeneric(
   // Unpack operands.
   std::vector<MlirValue> operands;
   operands.reserve(operands.size());
+  size_t index = 0;
   if (operandSegmentSpecObj.is_none()) {
     // Non-sized operand unpacking.
-    for (const auto &it : llvm::enumerate(operandList)) {
+    for (const auto &operand : operandList) {
       try {
-        operands.push_back(getOpResultOrValue(it.value()));
+        operands.push_back(getOpResultOrValue(operand));
       } catch (nb::builtin_exception &err) {
-        throw nb::value_error(join("Operand ", it.index(), " of operation \"",
-                                   name, "\" must be a Value (", err.what(),
-                                   ")")
+        throw nb::value_error(join("Operand ", index, " of operation \"", name,
+                                   "\" must be a Value (", err.what(), ")")
                                   .c_str());
       }
+      ++index;
     }
   } else {
     // Sized operand unpacking.
@@ -1659,20 +1661,19 @@ nb::object PyOpView::buildGeneric(
               .c_str());
     }
     operandSegmentLengths.reserve(operandList.size());
-    for (const auto &it :
-         llvm::enumerate(llvm::zip(operandList, operandSegmentSpec))) {
-      int segmentSpec = std::get<1>(it.value());
+    size_t size = operandSegmentSpec.size();
+    for (size_t index = 0; index < size; ++index) {
+      int segmentSpec = operandSegmentSpec[index];
       if (segmentSpec == 1 || segmentSpec == 0) {
         // Unpack unary element.
-        auto &operand = std::get<0>(it.value());
+        const auto operand = operandList[index];
         if (!operand.is_none()) {
           try {
-
             operands.push_back(getOpResultOrValue(operand));
           } catch (nb::builtin_exception &err) {
-            throw nb::value_error(join("Operand ", it.index(),
-                                       " of operation \"", name,
-                                       "\" must be a Value (", err.what(), ")")
+            throw nb::value_error(join("Operand ", index, " of operation \"",
+                                       name, "\" must be a Value (", err.what(),
+                                       ")")
                                       .c_str());
           }
 
@@ -1682,19 +1683,19 @@ nb::object PyOpView::buildGeneric(
           operandSegmentLengths.push_back(0);
         } else {
           throw nb::value_error(
-              join("Operand ", it.index(), " of operation \"", name,
+              join("Operand ", index, " of operation \"", name,
                    "\" must be a Value (was None and operand is not optional)")
                   .c_str());
         }
       } else if (segmentSpec == -1) {
         // Unpack sequence by appending.
         try {
-          if (std::get<0>(it.value()).is_none()) {
+          if (operandList[index].is_none()) {
             // Treat it as an empty list.
             operandSegmentLengths.push_back(0);
           } else {
             // Unpack the list.
-            auto segment = nb::cast<nb::sequence>(std::get<0>(it.value()));
+            auto segment = nb::cast<nb::sequence>(operandList[index]);
             for (nb::handle segmentItem : segment) {
               operands.push_back(getOpResultOrValue(segmentItem));
             }
@@ -1704,7 +1705,7 @@ nb::object PyOpView::buildGeneric(
           // NOTE: Sloppy to be using a catch-all here, but there are at least
           // three different unrelated exceptions that can be thrown in the
           // above "casts". Just keep the scope above small and catch them all.
-          throw nb::value_error(join("Operand ", it.index(), " of operation \"",
+          throw nb::value_error(join("Operand ", index, " of operation \"",
                                      name, "\" must be a Sequence of Values (",
                                      err.what(), ")")
                                     .c_str());

>From 274f949a38e20a08d570303d37e6d12dfd116377 Mon Sep 17 00:00:00 2001
From: Amily Wu <amilywu2 at amd.com>
Date: Wed, 28 Jan 2026 22:15:52 +0000
Subject: [PATCH 2/6] Clean Arrayref

---
 mlir/lib/Bindings/Python/IRCore.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/mlir/lib/Bindings/Python/IRCore.cpp b/mlir/lib/Bindings/Python/IRCore.cpp
index 8fe5f855ef450..9e0ed91003463 100644
--- a/mlir/lib/Bindings/Python/IRCore.cpp
+++ b/mlir/lib/Bindings/Python/IRCore.cpp
@@ -3167,9 +3167,9 @@ void populateIRCore(nb::module_ &m) {
             if (frames.empty())
               throw nb::value_error("No caller frames provided.");
             MlirLocation caller = frames.back().get();
-            for (const PyLocation &frame :
-                 llvm::reverse(llvm::ArrayRef(frames).drop_back()))
-              caller = mlirLocationCallSiteGet(frame.get(), caller);
+            for (size_t index = frames.size() - 1; index-- > 0;) {
+              caller = mlirLocationCallSiteGet(frames[index].get(), caller);
+            }
             return PyLocation(context->getRef(),
                               mlirLocationCallSiteGet(callee.get(), caller));
           },

>From c2215cbe4bd41c526c5711e12c524980fa13e118 Mon Sep 17 00:00:00 2001
From: Amily Wu <amilywu2 at amd.com>
Date: Wed, 28 Jan 2026 22:46:05 +0000
Subject: [PATCH 3/6] Clean llvm hash value

---
 mlir/lib/Bindings/Python/IRCore.cpp | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/mlir/lib/Bindings/Python/IRCore.cpp b/mlir/lib/Bindings/Python/IRCore.cpp
index 9e0ed91003463..02313f434b652 100644
--- a/mlir/lib/Bindings/Python/IRCore.cpp
+++ b/mlir/lib/Bindings/Python/IRCore.cpp
@@ -19,6 +19,7 @@
 #include "mlir-c/IR.h"
 #include "mlir-c/Support.h"
 
+#include <functional>
 #include <optional>
 #include <sstream>
 #include <string>
@@ -4099,7 +4100,8 @@ void populateIRCore(nb::module_ &m) {
       .def(
           "__hash__",
           [](PyBlock &self) {
-            return static_cast<size_t>(llvm::hash_value(self.get().ptr));
+            return static_cast<size_t>(
+                std::hash<decltype(self.get().ptr)>{}(self.get().ptr));
           },
           "Returns the hash value of the block.")
       .def(
@@ -4287,7 +4289,8 @@ void populateIRCore(nb::module_ &m) {
       .def(
           "__hash__",
           [](PyAttribute &self) {
-            return static_cast<size_t>(llvm::hash_value(self.get().ptr));
+            return static_cast<size_t>(
+                std::hash<decltype(self.get().ptr)>{}(self.get().ptr));
           },
           "Returns the hash value of the attribute.")
       .def(
@@ -4412,7 +4415,8 @@ void populateIRCore(nb::module_ &m) {
       .def(
           "__hash__",
           [](PyType &self) {
-            return static_cast<size_t>(llvm::hash_value(self.get().ptr));
+            return static_cast<size_t>(
+                std::hash<decltype(self.get().ptr)>{}(self.get().ptr));
           },
           "Returns the hash value of the `Type`.")
       .def(
@@ -4554,7 +4558,8 @@ void populateIRCore(nb::module_ &m) {
       .def(
           "__hash__",
           [](PyValue &self) {
-            return static_cast<size_t>(llvm::hash_value(self.get().ptr));
+            return static_cast<size_t>(
+                std::hash<decltype(self.get().ptr)>{}(self.get().ptr));
           },
           "Returns the hash value of the value.")
       .def(

>From 48546d203b4881ec3e7a40fc8dad813e5809a408 Mon Sep 17 00:00:00 2001
From: Amily Wu <amilywu2 at amd.com>
Date: Thu, 29 Jan 2026 16:33:58 +0000
Subject: [PATCH 4/6] Add type hints

---
 mlir/lib/Bindings/Python/IRCore.cpp | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/mlir/lib/Bindings/Python/IRCore.cpp b/mlir/lib/Bindings/Python/IRCore.cpp
index 02313f434b652..55fcc493c282a 100644
--- a/mlir/lib/Bindings/Python/IRCore.cpp
+++ b/mlir/lib/Bindings/Python/IRCore.cpp
@@ -88,14 +88,14 @@ MlirBlock createBlock(const nb::sequence &pyArgTypes,
                       const std::optional<nb::sequence> &pyArgLocs) {
   std::vector<MlirType> argTypes;
   argTypes.reserve(nb::len(pyArgTypes));
-  for (const auto &pyType : pyArgTypes)
+  for (nb::handle pyType : pyArgTypes)
     argTypes.push_back(
         nb::cast<python::MLIR_BINDINGS_PYTHON_DOMAIN::PyType &>(pyType));
 
   std::vector<MlirLocation> argLocs;
   if (pyArgLocs) {
     argLocs.reserve(nb::len(*pyArgLocs));
-    for (const auto &pyLoc : *pyArgLocs)
+    for (nb::handle pyLoc : *pyArgLocs)
       argLocs.push_back(
           nb::cast<python::MLIR_BINDINGS_PYTHON_DOMAIN::PyLocation &>(pyLoc));
   } else if (!argTypes.empty()) {
@@ -1315,7 +1315,7 @@ nb::object PyOperation::create(std::string_view name,
   // Unpack/validate successors.
   if (successors) {
     mlirSuccessors.reserve(successors->size());
-    for (auto *successor : *successors) {
+    for (PyBlock *successor : *successors) {
       // TODO: Verify successor originate from the same context.
       if (!successor)
         throw nb::value_error("successor block cannot be None");
@@ -1339,7 +1339,7 @@ nb::object PyOperation::create(std::string_view name,
     // on.
     std::vector<MlirNamedAttribute> mlirNamedAttributes;
     mlirNamedAttributes.reserve(mlirAttributes.size());
-    for (auto &it : mlirAttributes)
+    for (const std::pair<std::string, MlirAttribute> &it : mlirAttributes)
       mlirNamedAttributes.push_back(mlirNamedAttributeGet(
           mlirIdentifierGet(mlirAttributeGetContext(it.second),
                             toMlirStringRef(it.first)),
@@ -1478,7 +1478,7 @@ static void populateResultTypes(std::string_view name, nb::list resultTypeList,
   if (resultSegmentSpecObj.is_none()) {
     // Non-variadic result unpacking.
     size_t index = 0;
-    for (const auto &resultType : resultTypeList) {
+    for (nb::handle resultType : resultTypeList) {
       try {
         resultTypes.push_back(nb::cast<PyType *>(resultType));
         if (!resultTypes.back())
@@ -1642,7 +1642,7 @@ nb::object PyOpView::buildGeneric(
   size_t index = 0;
   if (operandSegmentSpecObj.is_none()) {
     // Non-sized operand unpacking.
-    for (const auto &operand : operandList) {
+    for (nb::handle operand : operandList) {
       try {
         operands.push_back(getOpResultOrValue(operand));
       } catch (nb::builtin_exception &err) {
@@ -3239,7 +3239,7 @@ void populateIRCore(nb::module_ &m) {
              DefaultingPyMlirContext context) {
             std::vector<MlirLocation> locations;
             locations.reserve(pyLocations.size());
-            for (auto &pyLocation : pyLocations)
+            for (const PyLocation &pyLocation : pyLocations)
               locations.push_back(pyLocation.get());
             MlirLocation location = mlirLocationFusedGet(
                 context->get(), locations.size(), locations.data(),

>From b5e1a58de6a42ef13014b7ca674a86079e312bb6 Mon Sep 17 00:00:00 2001
From: Amily Wu <amilywu2 at amd.com>
Date: Thu, 29 Jan 2026 16:40:13 +0000
Subject: [PATCH 5/6] Change for loop style

---
 mlir/lib/Bindings/Python/IRCore.cpp | 39 +++++++++++++----------------
 1 file changed, 18 insertions(+), 21 deletions(-)

diff --git a/mlir/lib/Bindings/Python/IRCore.cpp b/mlir/lib/Bindings/Python/IRCore.cpp
index 55fcc493c282a..d889b892f166e 100644
--- a/mlir/lib/Bindings/Python/IRCore.cpp
+++ b/mlir/lib/Bindings/Python/IRCore.cpp
@@ -1500,13 +1500,12 @@ static void populateResultTypes(std::string_view name, nb::list resultTypeList,
               .c_str());
     }
     resultSegmentLengths.reserve(resultTypeList.size());
-    size_t size = resultSegmentSpec.size();
-    for (size_t index = 0; index < size; ++index) {
-      int segmentSpec = resultSegmentSpec[index];
+    for (size_t i = 0, e = resultSegmentSpec.size(); i < e; ++i) {
+      int segmentSpec = resultSegmentSpec[i];
       if (segmentSpec == 1 || segmentSpec == 0) {
         // Unpack unary element.
         try {
-          auto *resultType = nb::cast<PyType *>(resultTypeList[index]);
+          auto *resultType = nb::cast<PyType *>(resultTypeList[i]);
           if (resultType) {
             resultTypes.push_back(resultType);
             resultSegmentLengths.push_back(1);
@@ -1515,24 +1514,24 @@ static void populateResultTypes(std::string_view name, nb::list resultTypeList,
             resultSegmentLengths.push_back(0);
           } else {
             throw nb::value_error(
-                join("Result ", index, " of operation \"", name,
+                join("Result ", i, " of operation \"", name,
                      "\" must be a Type (was None and result is not optional)")
                     .c_str());
           }
         } catch (nb::cast_error &err) {
-          throw nb::value_error(join("Result ", index, " of operation \"", name,
+          throw nb::value_error(join("Result ", i, " of operation \"", name,
                                      "\" must be a Type (", err.what(), ")")
                                     .c_str());
         }
       } else if (segmentSpec == -1) {
         // Unpack sequence by appending.
         try {
-          if (resultTypeList[index].is_none()) {
+          if (resultTypeList[i].is_none()) {
             // Treat it as an empty list.
             resultSegmentLengths.push_back(0);
           } else {
             // Unpack the list.
-            auto segment = nb::cast<nb::sequence>(resultTypeList[index]);
+            auto segment = nb::cast<nb::sequence>(resultTypeList[i]);
             for (nb::handle segmentItem : segment) {
               resultTypes.push_back(nb::cast<PyType *>(segmentItem));
               if (!resultTypes.back()) {
@@ -1545,7 +1544,7 @@ static void populateResultTypes(std::string_view name, nb::list resultTypeList,
           // NOTE: Sloppy to be using a catch-all here, but there are at least
           // three different unrelated exceptions that can be thrown in the
           // above "casts". Just keep the scope above small and catch them all.
-          throw nb::value_error(join("Result ", index, " of operation \"", name,
+          throw nb::value_error(join("Result ", i, " of operation \"", name,
                                      "\" must be a Sequence of Types (",
                                      err.what(), ")")
                                     .c_str());
@@ -1662,19 +1661,17 @@ nb::object PyOpView::buildGeneric(
               .c_str());
     }
     operandSegmentLengths.reserve(operandList.size());
-    size_t size = operandSegmentSpec.size();
-    for (size_t index = 0; index < size; ++index) {
-      int segmentSpec = operandSegmentSpec[index];
+    for (size_t i = 0, e = operandSegmentSpec.size(); i < e; ++i) {
+      int segmentSpec = operandSegmentSpec[i];
       if (segmentSpec == 1 || segmentSpec == 0) {
         // Unpack unary element.
-        const auto operand = operandList[index];
+        const auto operand = operandList[i];
         if (!operand.is_none()) {
           try {
             operands.push_back(getOpResultOrValue(operand));
           } catch (nb::builtin_exception &err) {
-            throw nb::value_error(join("Operand ", index, " of operation \"",
-                                       name, "\" must be a Value (", err.what(),
-                                       ")")
+            throw nb::value_error(join("Operand ", i, " of operation \"", name,
+                                       "\" must be a Value (", err.what(), ")")
                                       .c_str());
           }
 
@@ -1684,19 +1681,19 @@ nb::object PyOpView::buildGeneric(
           operandSegmentLengths.push_back(0);
         } else {
           throw nb::value_error(
-              join("Operand ", index, " of operation \"", name,
+              join("Operand ", i, " of operation \"", name,
                    "\" must be a Value (was None and operand is not optional)")
                   .c_str());
         }
       } else if (segmentSpec == -1) {
         // Unpack sequence by appending.
         try {
-          if (operandList[index].is_none()) {
+          if (operandList[i].is_none()) {
             // Treat it as an empty list.
             operandSegmentLengths.push_back(0);
           } else {
             // Unpack the list.
-            auto segment = nb::cast<nb::sequence>(operandList[index]);
+            auto segment = nb::cast<nb::sequence>(operandList[i]);
             for (nb::handle segmentItem : segment) {
               operands.push_back(getOpResultOrValue(segmentItem));
             }
@@ -1706,8 +1703,8 @@ nb::object PyOpView::buildGeneric(
           // NOTE: Sloppy to be using a catch-all here, but there are at least
           // three different unrelated exceptions that can be thrown in the
           // above "casts". Just keep the scope above small and catch them all.
-          throw nb::value_error(join("Operand ", index, " of operation \"",
-                                     name, "\" must be a Sequence of Values (",
+          throw nb::value_error(join("Operand ", i, " of operation \"", name,
+                                     "\" must be a Sequence of Values (",
                                      err.what(), ")")
                                     .c_str());
         }

>From b860c253d356a42ab4ebb325b75840fdd4175a37 Mon Sep 17 00:00:00 2001
From: Amily Wu <amilywu2 at amd.com>
Date: Thu, 29 Jan 2026 16:56:01 +0000
Subject: [PATCH 6/6] Add hash func

---
 mlir/lib/Bindings/Python/IRCore.cpp | 30 ++++++++++-------------------
 1 file changed, 10 insertions(+), 20 deletions(-)

diff --git a/mlir/lib/Bindings/Python/IRCore.cpp b/mlir/lib/Bindings/Python/IRCore.cpp
index d889b892f166e..c7653f1ee4b15 100644
--- a/mlir/lib/Bindings/Python/IRCore.cpp
+++ b/mlir/lib/Bindings/Python/IRCore.cpp
@@ -57,6 +57,12 @@ static std::string join(const Ts &...args) {
   return oss.str();
 }
 
+/// Local helper to compute std::hash for a value.
+template <typename T>
+static size_t hash(const T &value) {
+  return std::hash<T>{}(value);
+}
+
 /// Helper for creating an @classmethod.
 template <class Func, typename... Args>
 static nb::object classmethod(Func f, Args... args) {
@@ -4095,11 +4101,7 @@ void populateIRCore(nb::module_ &m) {
           "__eq__", [](PyBlock &self, nb::object &other) { return false; },
           "Compares block with non-block object (always returns False).")
       .def(
-          "__hash__",
-          [](PyBlock &self) {
-            return static_cast<size_t>(
-                std::hash<decltype(self.get().ptr)>{}(self.get().ptr));
-          },
+          "__hash__", [](PyBlock &self) { return hash(self.get().ptr); },
           "Returns the hash value of the block.")
       .def(
           "__str__",
@@ -4284,11 +4286,7 @@ void populateIRCore(nb::module_ &m) {
           "Compares attribute with non-attribute object (always returns "
           "False).")
       .def(
-          "__hash__",
-          [](PyAttribute &self) {
-            return static_cast<size_t>(
-                std::hash<decltype(self.get().ptr)>{}(self.get().ptr));
-          },
+          "__hash__", [](PyAttribute &self) { return hash(self.get().ptr); },
           "Returns the hash value of the attribute.")
       .def(
           "dump", [](PyAttribute &self) { mlirAttributeDump(self); },
@@ -4410,11 +4408,7 @@ void populateIRCore(nb::module_ &m) {
           "other"_a.none(),
           "Compares type with non-type object (always returns False).")
       .def(
-          "__hash__",
-          [](PyType &self) {
-            return static_cast<size_t>(
-                std::hash<decltype(self.get().ptr)>{}(self.get().ptr));
-          },
+          "__hash__", [](PyType &self) { return hash(self.get().ptr); },
           "Returns the hash value of the `Type`.")
       .def(
           "dump", [](PyType &self) { mlirTypeDump(self); }, kDumpDocstring)
@@ -4553,11 +4547,7 @@ void populateIRCore(nb::module_ &m) {
           "__eq__", [](PyValue &self, nb::object other) { return false; },
           "Compares value with non-value object (always returns False).")
       .def(
-          "__hash__",
-          [](PyValue &self) {
-            return static_cast<size_t>(
-                std::hash<decltype(self.get().ptr)>{}(self.get().ptr));
-          },
+          "__hash__", [](PyValue &self) { return hash(self.get().ptr); },
           "Returns the hash value of the value.")
       .def(
           "__str__",



More information about the Mlir-commits mailing list