diff --git a/mlir/include/mlir/Bindings/Python/Globals.h b/mlir/include/mlir/Bindings/Python/Globals.h index bdcabea76cd3c..23cccdd36279a 100644 --- a/mlir/include/mlir/Bindings/Python/Globals.h +++ b/mlir/include/mlir/Bindings/Python/Globals.h @@ -23,7 +23,6 @@ #include "mlir/CAPI/Support.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/StringRef.h" #include "llvm/Support/Regex.h" namespace mlir { @@ -127,7 +126,7 @@ class MLIR_PYTHON_API_EXPORTED PyGlobals { /// name. Note that this may trigger a load of the dialect, which can /// arbitrarily re-enter. std::optional - lookupOpAdaptorClass(llvm::StringRef operationName); + lookupOpAdaptorClass(std::string_view operationName); class MLIR_PYTHON_API_EXPORTED TracebackLoc { public: diff --git a/mlir/include/mlir/Bindings/Python/IRAttributes.h b/mlir/include/mlir/Bindings/Python/IRAttributes.h index 5ff9afd0875f1..d5d5548602114 100644 --- a/mlir/include/mlir/Bindings/Python/IRAttributes.h +++ b/mlir/include/mlir/Bindings/Python/IRAttributes.h @@ -13,6 +13,7 @@ #include #include #include +#include #include "mlir-c/BuiltinAttributes.h" #include "mlir-c/BuiltinTypes.h" @@ -31,13 +32,13 @@ struct nb_buffer_info { ssize_t size = 0; const char *format = nullptr; ssize_t ndim = 0; - SmallVector shape; - SmallVector strides; + std::vector shape; + std::vector strides; bool readonly = false; nb_buffer_info( void *ptr, ssize_t itemsize, const char *format, ssize_t ndim, - SmallVector shape_in, SmallVector strides_in, + std::vector shape_in, std::vector strides_in, bool readonly = false, std::unique_ptr owned_view_in = std::unique_ptr(nullptr, nullptr)); @@ -462,11 +463,11 @@ class MLIR_PYTHON_API_EXPORTED PyDenseElementsAttribute Type *data = static_cast( const_cast(mlirDenseElementsAttrGetRawData(*this))); // Prepare the shape for the buffer_info. - SmallVector shape; + std::vector shape; for (intptr_t i = 0; i < rank; ++i) shape.push_back(mlirShapedTypeGetDimSize(shapedType, i)); // Prepare the strides for the buffer_info. - SmallVector strides; + std::vector strides; if (mlirDenseElementsAttrIsSplat(*this)) { // Splats are special, only the single value is stored. strides.assign(rank, 0); diff --git a/mlir/include/mlir/Bindings/Python/NanobindUtils.h b/mlir/include/mlir/Bindings/Python/NanobindUtils.h index b72ed31a4a4e5..2bd1025c49c36 100644 --- a/mlir/include/mlir/Bindings/Python/NanobindUtils.h +++ b/mlir/include/mlir/Bindings/Python/NanobindUtils.h @@ -12,10 +12,6 @@ #include "mlir-c/Support.h" #include "mlir/Bindings/Python/Nanobind.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Twine.h" -#include "llvm/Support/DataTypes.h" #include #include @@ -340,7 +336,7 @@ class Sliceable { /// Returns a new instance of the pseudo-container restricted to the given /// slice. Returns a nullptr object on failure. nanobind::object getItemSlice(PyObject *slice) { - ssize_t start, stop, extraStep, sliceLength; + Py_ssize_t start, stop, extraStep, sliceLength; if (PySlice_GetIndicesEx(slice, length, &start, &stop, &extraStep, &sliceLength) != 0) { PyErr_SetString(PyExc_IndexError, "index out of range"); diff --git a/mlir/lib/Bindings/Python/ExecutionEngineModule.cpp b/mlir/lib/Bindings/Python/ExecutionEngineModule.cpp index 01b7930deffd2..76dbd54ef0467 100644 --- a/mlir/lib/Bindings/Python/ExecutionEngineModule.cpp +++ b/mlir/lib/Bindings/Python/ExecutionEngineModule.cpp @@ -6,6 +6,8 @@ // //===----------------------------------------------------------------------===// +#include + #include "mlir-c/ExecutionEngine.h" #include "mlir/Bindings/Python/IRCore.h" #include "mlir/Bindings/Python/Nanobind.h" @@ -83,7 +85,8 @@ NB_MODULE(_mlirExecutionEngine, m) { [](PyExecutionEngine &self, PyModule &module, int optLevel, const std::vector &sharedLibPaths, bool enableObjectDump, bool enablePIC) { - llvm::SmallVector libPaths; + std::vector libPaths; + libPaths.reserve(sharedLibPaths.size()); for (const std::string &path : sharedLibPaths) libPaths.push_back({path.c_str(), path.length()}); MlirExecutionEngine executionEngine = mlirExecutionEngineCreate( diff --git a/mlir/lib/Bindings/Python/Globals.cpp b/mlir/lib/Bindings/Python/Globals.cpp index 1fcd83c15c6ce..d39ebfa1f518c 100644 --- a/mlir/lib/Bindings/Python/Globals.cpp +++ b/mlir/lib/Bindings/Python/Globals.cpp @@ -86,11 +86,10 @@ void PyGlobals::registerAttributeBuilder(const std::string &attributeKind, nb::ft_lock_guard lock(mutex); nb::object &found = attributeBuilderMap[attributeKind]; if (found && !replace) { - throw std::runtime_error((llvm::Twine("Attribute builder for '") + - attributeKind + - "' is already registered with func: " + - nb::cast(nb::str(found))) - .str()); + throw std::runtime_error( + nanobind::detail::join("Attribute builder for '", attributeKind, + "' is already registered with func: ", + nb::cast(nb::str(found)))); } found = std::move(pyFunc); } @@ -120,9 +119,8 @@ void PyGlobals::registerDialectImpl(const std::string &dialectNamespace, nb::ft_lock_guard lock(mutex); nb::object &found = dialectClassMap[dialectNamespace]; if (found) { - throw std::runtime_error((llvm::Twine("Dialect namespace '") + - dialectNamespace + "' is already registered.") - .str()); + throw std::runtime_error(nanobind::detail::join( + "Dialect namespace '", dialectNamespace, "' is already registered.")); } found = std::move(pyClass); } @@ -132,9 +130,8 @@ void PyGlobals::registerOperationImpl(const std::string &operationName, nb::ft_lock_guard lock(mutex); nb::object &found = operationClassMap[operationName]; if (found && !replace) { - throw std::runtime_error((llvm::Twine("Operation '") + operationName + - "' is already registered.") - .str()); + throw std::runtime_error(nanobind::detail::join( + "Operation '", operationName, "' is already registered.")); } found = std::move(pyClass); } @@ -144,9 +141,8 @@ void PyGlobals::registerOpAdaptorImpl(const std::string &operationName, nb::ft_lock_guard lock(mutex); nb::object &found = opAdaptorClassMap[operationName]; if (found && !replace) { - throw std::runtime_error((llvm::Twine("Operation adaptor of '") + - operationName + "' is already registered.") - .str()); + throw std::runtime_error(nanobind::detail::join( + "Operation adaptor of '", operationName, "' is already registered.")); } found = std::move(pyClass); } @@ -222,10 +218,10 @@ PyGlobals::lookupOperationClass(std::string_view operationName) { } std::optional -PyGlobals::lookupOpAdaptorClass(llvm::StringRef operationName) { +PyGlobals::lookupOpAdaptorClass(std::string_view operationName) { // Make sure dialect module is loaded. - auto split = operationName.split('.'); - llvm::StringRef dialectNamespace = split.first; + std::string_view dialectNamespace = + operationName.substr(0, operationName.find('.')); (void)loadDialectModule(dialectNamespace); nb::ft_lock_guard lock(mutex); diff --git a/mlir/lib/Bindings/Python/IRAffine.cpp b/mlir/lib/Bindings/Python/IRAffine.cpp index 2e760e6e6f830..131481b830c4d 100644 --- a/mlir/lib/Bindings/Python/IRAffine.cpp +++ b/mlir/lib/Bindings/Python/IRAffine.cpp @@ -8,8 +8,10 @@ #include #include +#include #include #include +#include #include #include @@ -23,19 +25,11 @@ #include "mlir-c/IntegerSet.h" #include "mlir/Bindings/Python/Nanobind.h" #include "mlir/Support/LLVM.h" -#include "llvm/ADT/Hashing.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Twine.h" namespace nb = nanobind; using namespace mlir; using namespace mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN; -using llvm::SmallVector; -using llvm::StringRef; -using llvm::Twine; - static const char kDumpDocstring[] = R"(Dumps a debug representation of the object to stderr.)"; @@ -44,22 +38,19 @@ static const char kDumpDocstring[] = /// Throws errors in case of failure, using "action" to describe what the caller /// was attempting to do. template -static void pyListToVector(const nb::list &list, - llvm::SmallVectorImpl &result, - StringRef action) { +static void pyListToVector(const nb::list &list, std::vector &result, + std::string_view action) { result.reserve(nb::len(list)); for (nb::handle item : list) { try { result.push_back(nb::cast(item)); } catch (nb::cast_error &err) { - std::string msg = (llvm::Twine("Invalid expression when ") + action + - " (" + err.what() + ")") - .str(); + std::string msg = nanobind::detail::join("Invalid expression when ", + action, " (", err.what(), ")"); throw std::runtime_error(msg.c_str()); } catch (std::runtime_error &err) { - std::string msg = (llvm::Twine("Invalid expression (None?) when ") + - action + " (" + err.what() + ")") - .str(); + std::string msg = nanobind::detail::join( + "Invalid expression (None?) when ", action, " (", err.what(), ")"); throw std::runtime_error(msg.c_str()); } } @@ -67,7 +58,7 @@ static void pyListToVector(const nb::list &list, template static bool isPermutation(const std::vector &permutation) { - llvm::SmallVector seen(permutation.size(), false); + std::vector seen(permutation.size(), false); for (auto val : permutation) { if (val < permutation.size()) { if (seen[val]) @@ -106,11 +97,11 @@ class PyConcreteAffineExpr : public BaseTy { static MlirAffineExpr castFrom(PyAffineExpr &orig) { if (!DerivedTy::isaFunction(orig)) { auto origRepr = nb::cast(nb::repr(nb::cast(orig))); - throw nb::value_error((Twine("Cannot cast affine expression to ") + - DerivedTy::pyClassName + " (from " + origRepr + - ")") - .str() - .c_str()); + throw nb::value_error( + nanobind::detail::join("Cannot cast affine expression to ", + DerivedTy::pyClassName, " (from ", origRepr, + ")") + .c_str()); } return orig; } @@ -602,7 +593,7 @@ void populateIRAffine(nb::module_ &m) { }) .def("__hash__", [](PyAffineExpr &self) { - return static_cast(llvm::hash_value(self.get().ptr)); + return std::hash{}(self.get().ptr); }) .def_prop_ro( "context", @@ -739,12 +730,12 @@ void populateIRAffine(nb::module_ &m) { }) .def("__hash__", [](PyAffineMap &self) { - return static_cast(llvm::hash_value(self.get().ptr)); + return std::hash{}(self.get().ptr); }) .def_static( "compress_unused_symbols", [](const nb::list &affineMaps, DefaultingPyMlirContext context) { - SmallVector maps; + std::vector maps; pyListToVector( affineMaps, maps, "attempting to create an AffineMap"); std::vector compressed(affineMaps.size()); @@ -772,7 +763,7 @@ void populateIRAffine(nb::module_ &m) { "get", [](intptr_t dimCount, intptr_t symbolCount, const nb::list &exprs, DefaultingPyMlirContext context) { - SmallVector affineExprs; + std::vector affineExprs; pyListToVector( exprs, affineExprs, "attempting to create an AffineMap"); MlirAffineMap map = @@ -925,7 +916,7 @@ void populateIRAffine(nb::module_ &m) { }) .def("__hash__", [](PyIntegerSet &self) { - return static_cast(llvm::hash_value(self.get().ptr)); + return std::hash{}(self.get().ptr); }) .def_prop_ro( "context", @@ -946,17 +937,14 @@ void populateIRAffine(nb::module_ &m) { if (exprs.size() == 0) throw nb::value_error("Expected non-empty list of constraints"); - // Copy over to a SmallVector because std::vector has a - // specialization for booleans that packs data and does not - // expose a `bool *`. - SmallVector flags(eqFlags.begin(), eqFlags.end()); - - SmallVector affineExprs; + // std::vector does not expose a bool* data pointer. + std::vector flags(eqFlags.begin(), eqFlags.end()); + std::vector affineExprs; pyListToVector(exprs, affineExprs, "attempting to create an IntegerSet"); MlirIntegerSet set = mlirIntegerSetGet( context->get(), numDims, numSymbols, exprs.size(), - affineExprs.data(), flags.data()); + affineExprs.data(), reinterpret_cast(flags.data())); return PyIntegerSet(context->getRef(), set); }, nb::arg("num_dims"), nb::arg("num_symbols"), nb::arg("exprs"), @@ -987,7 +975,8 @@ void populateIRAffine(nb::module_ &m) { "Expected the number of symbol replacement expressions " "to match that of symbols"); - SmallVector dimAffineExprs, symbolAffineExprs; + std::vector dimAffineExprs; + std::vector symbolAffineExprs; pyListToVector( dimExprs, dimAffineExprs, "attempting to create an IntegerSet by replacing dimensions"); diff --git a/mlir/lib/Bindings/Python/IRAttributes.cpp b/mlir/lib/Bindings/Python/IRAttributes.cpp index 05c0c5e825df3..c271497fcc9f8 100644 --- a/mlir/lib/Bindings/Python/IRAttributes.cpp +++ b/mlir/lib/Bindings/Python/IRAttributes.cpp @@ -6,12 +6,14 @@ // //===----------------------------------------------------------------------===// +#include #include #include #include #include #include #include +#include #include "mlir-c/BuiltinAttributes.h" #include "mlir-c/BuiltinTypes.h" @@ -21,15 +23,12 @@ #include "mlir/Bindings/Python/NanobindAdaptors.h" #include "mlir/Bindings/Python/NanobindUtils.h" #include "llvm/ADT/ScopeExit.h" -#include "llvm/Support/raw_ostream.h" namespace nb = nanobind; using namespace nanobind::literals; using namespace mlir; using namespace mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN; -using llvm::SmallVector; - //------------------------------------------------------------------------------ // Docstrings (trivial, non-duplicated docstrings are included inline). //------------------------------------------------------------------------------ @@ -129,7 +128,7 @@ namespace MLIR_BINDINGS_PYTHON_DOMAIN { nb_buffer_info::nb_buffer_info( void *ptr, ssize_t itemsize, const char *format, ssize_t ndim, - SmallVector shape_in, SmallVector strides_in, + std::vector shape_in, std::vector strides_in, bool readonly, std::unique_ptr owned_view_in) : ptr(ptr), itemsize(itemsize), format(format), ndim(ndim), @@ -255,7 +254,7 @@ void PyArrayAttribute::bindDerived(ClassTy &c) { c.def_static( "get", [](const nb::list &attributes, DefaultingPyMlirContext context) { - SmallVector mlirAttributes; + std::vector mlirAttributes; mlirAttributes.reserve(nb::len(attributes)); for (auto attribute : attributes) { mlirAttributes.push_back(pyTryCast(attribute)); @@ -465,7 +464,7 @@ PySymbolRefAttribute::fromList(const std::vector &symbols, throw std::runtime_error("SymbolRefAttr must be composed of at least " "one symbol."); MlirStringRef rootSymbol = toMlirStringRef(symbols[0]); - SmallVector referenceAttrs; + std::vector referenceAttrs; for (size_t i = 1; i < symbols.size(); ++i) { referenceAttrs.push_back( mlirFlatSymbolRefAttrGet(context.get(), toMlirStringRef(symbols[i]))); @@ -566,22 +565,21 @@ PyDenseElementsAttribute::getFromList(const nb::list &attributes, if ((!mlirTypeIsAShaped(*explicitType) || !mlirShapedTypeHasStaticShape(*explicitType))) { - std::string message; - llvm::raw_string_ostream os(message); - os << "Expected a static ShapedType for the shaped_type parameter: " - << nb::cast(nb::repr(nb::cast(*explicitType))); + std::string message = nanobind::detail::join( + "Expected a static ShapedType for the shaped_type parameter: ", + nb::cast(nb::repr(nb::cast(*explicitType)))); throw nb::value_error(message.c_str()); } shapedType = *explicitType; } else { - SmallVector shape = {static_cast(numAttributes)}; + std::vector shape = {static_cast(numAttributes)}; shapedType = mlirRankedTensorTypeGet( shape.size(), shape.data(), mlirAttributeGetType(pyTryCast(attributes[0])), mlirAttributeGetNull()); } - SmallVector mlirAttributes; + std::vector mlirAttributes; mlirAttributes.reserve(numAttributes); for (const nb::handle &attribute : attributes) { MlirAttribute mlirAttribute = pyTryCast(attribute); @@ -589,12 +587,11 @@ PyDenseElementsAttribute::getFromList(const nb::list &attributes, mlirAttributes.push_back(mlirAttribute); if (!mlirTypeEqual(mlirShapedTypeGetElementType(shapedType), attrType)) { - std::string message; - llvm::raw_string_ostream os(message); - os << "All attributes must be of the same type and match " - << "the type parameter: expected=" - << nb::cast(nb::repr(nb::cast(shapedType))) - << ", but got=" << nb::cast(nb::repr(nb::cast(attrType))); + std::string message = nanobind::detail::join( + "All attributes must be of the same type and match the type " + "parameter: expected=", + nb::cast(nb::repr(nb::cast(shapedType))), + ", but got=", nb::cast(nb::repr(nb::cast(attrType)))); throw nb::value_error(message.c_str()); } } @@ -810,11 +807,11 @@ bool PyDenseElementsAttribute::isSignedIntegerFormat(std::string_view format) { MlirType PyDenseElementsAttribute::getShapedType( std::optional bulkLoadElementType, std::optional> explicitShape, Py_buffer &view) { - SmallVector shape; + std::vector shape; if (explicitShape) { - shape.append(explicitShape->begin(), explicitShape->end()); + shape.insert(shape.end(), explicitShape->begin(), explicitShape->end()); } else { - shape.append(view.shape, view.shape + view.ndim); + shape.insert(shape.end(), view.shape, view.shape + view.ndim); } if (mlirTypeIsAShaped(*bulkLoadElementType)) { @@ -1199,7 +1196,7 @@ void PyDictAttribute::bindDerived(ClassTy &c) { c.def_static( "get", [](const nb::dict &attributes, DefaultingPyMlirContext context) { - SmallVector mlirNamedAttributes; + std::vector mlirNamedAttributes; mlirNamedAttributes.reserve(attributes.size()); for (std::pair it : attributes) { auto &mlirAttr = nb::cast(it.second); @@ -1303,7 +1300,7 @@ void PyStridedLayoutAttribute::bindDerived(ClassTy &c) { [](int64_t rank, DefaultingPyMlirContext ctx) { auto dynamic = mlirShapedTypeGetDynamicStrideOrOffset(); std::vector strides(rank); - llvm::fill(strides, dynamic); + std::fill(strides.begin(), strides.end(), dynamic); MlirAttribute attr = mlirStridedLayoutAttrGet( ctx->get(), dynamic, strides.size(), strides.data()); return PyStridedLayoutAttribute(ctx->getRef(), attr); diff --git a/mlir/lib/Bindings/Python/IRInterfaces.cpp b/mlir/lib/Bindings/Python/IRInterfaces.cpp index 09112d4989ae4..be60426473e0d 100644 --- a/mlir/lib/Bindings/Python/IRInterfaces.cpp +++ b/mlir/lib/Bindings/Python/IRInterfaces.cpp @@ -18,8 +18,6 @@ #include "mlir-c/Support.h" #include "mlir/Bindings/Python/IRCore.h" #include "mlir/Bindings/Python/Nanobind.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/SmallVector.h" namespace nb = nanobind; @@ -48,10 +46,10 @@ its return shaped type components. Raises ValueError on failure.)"; namespace { -/// Takes in an optional ist of operands and converts them into a SmallVector -/// of MlirVlaues. Returns an empty SmallVector if the list is empty. -llvm::SmallVector wrapOperands(std::optional operandList) { - llvm::SmallVector mlirOperands; +/// Takes in an optional ist of operands and converts them into a std::vector +/// of MlirVlaues. Returns an empty std::vector if the list is empty. +std::vector wrapOperands(std::optional operandList) { + std::vector mlirOperands; if (!operandList || operandList->size() == 0) { return mlirOperands; @@ -59,13 +57,15 @@ llvm::SmallVector wrapOperands(std::optional operandList) { // Note: as the list may contain other lists this may not be final size. mlirOperands.reserve(operandList->size()); - for (const auto &&it : llvm::enumerate(*operandList)) { - if (it.value().is_none()) + for (size_t i = 0, e = operandList->size(); i < e; ++i) { + nb::handle operand = (*operandList)[i]; + intptr_t index = static_cast(i); + if (operand.is_none()) continue; PyValue *val; try { - val = nb::cast(it.value()); + val = nb::cast(operand); if (!val) throw nb::cast_error(); mlirOperands.push_back(val->get()); @@ -76,7 +76,7 @@ llvm::SmallVector wrapOperands(std::optional operandList) { } try { - auto vals = nb::cast(it.value()); + auto vals = nb::cast(operand); for (nb::handle v : vals) { try { val = nb::cast(v); @@ -85,19 +85,19 @@ llvm::SmallVector wrapOperands(std::optional operandList) { mlirOperands.push_back(val->get()); } catch (nb::cast_error &err) { throw nb::value_error( - (llvm::Twine("Operand ") + llvm::Twine(it.index()) + - " must be a Value or Sequence of Values (" + err.what() + ")") - .str() + nanobind::detail::join("Operand ", index, + " must be a Value or Sequence of Values (", + err.what(), ")") .c_str()); } } continue; } catch (nb::cast_error &err) { - throw nb::value_error((llvm::Twine("Operand ") + llvm::Twine(it.index()) + - " must be a Value or Sequence of Values (" + - err.what() + ")") - .str() - .c_str()); + throw nb::value_error( + nanobind::detail::join("Operand ", index, + " must be a Value or Sequence of Values (", + err.what(), ")") + .c_str()); } throw nb::cast_error(); @@ -106,11 +106,11 @@ llvm::SmallVector wrapOperands(std::optional operandList) { return mlirOperands; } -/// Takes in an optional vector of PyRegions and returns a SmallVector of -/// MlirRegion. Returns an empty SmallVector if the list is empty. -llvm::SmallVector +/// Takes in an optional vector of PyRegions and returns a std::vector of +/// MlirRegion. Returns an empty std::vector if the list is empty. +std::vector wrapRegions(std::optional> regions) { - llvm::SmallVector mlirRegions; + std::vector mlirRegions; if (regions) { mlirRegions.reserve(regions->size()); @@ -273,9 +273,8 @@ class PyInferTypeOpInterface std::optional> regions, DefaultingPyMlirContext context, DefaultingPyLocation location) { - llvm::SmallVector mlirOperands = - wrapOperands(std::move(operandList)); - llvm::SmallVector mlirRegions = wrapRegions(std::move(regions)); + std::vector mlirOperands = wrapOperands(std::move(operandList)); + std::vector mlirRegions = wrapRegions(std::move(regions)); std::vector inferredTypes; PyMlirContext &pyContext = context.resolve(); @@ -430,9 +429,8 @@ class PyInferShapedTypeOpInterface std::optional attributes, void *properties, std::optional> regions, DefaultingPyMlirContext context, DefaultingPyLocation location) { - llvm::SmallVector mlirOperands = - wrapOperands(std::move(operandList)); - llvm::SmallVector mlirRegions = wrapRegions(std::move(regions)); + std::vector mlirOperands = wrapOperands(std::move(operandList)); + std::vector mlirRegions = wrapRegions(std::move(regions)); std::vector inferredShapedTypeComponents; PyMlirContext &pyContext = context.resolve(); diff --git a/mlir/lib/Bindings/Python/IRTypes.cpp b/mlir/lib/Bindings/Python/IRTypes.cpp index 94327f67e050e..a8e60f099ef67 100644 --- a/mlir/lib/Bindings/Python/IRTypes.cpp +++ b/mlir/lib/Bindings/Python/IRTypes.cpp @@ -24,7 +24,6 @@ using namespace mlir; using namespace mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN; using llvm::SmallVector; -using llvm::Twine; namespace mlir { namespace python { @@ -311,10 +310,10 @@ void PyComplexType::bindDerived(ClassTy &c) { return PyComplexType(elementType.getContext(), t); } throw nb::value_error( - (Twine("invalid '") + - nb::cast(nb::repr(nb::cast(elementType))) + - "' and expected floating point or integer type.") - .str() + nanobind::detail::join( + "invalid '", + nb::cast(nb::repr(nb::cast(elementType))), + "' and expected floating point or integer type.") .c_str()); }, "Create a complex type");