Skip to content

Spurious temporaries break non-copyable types #3253

Description

@pitrou

If I have a C++ API such as the following:

cdef extern from 'arrow/util/compression.h' namespace 'arrow' nogil:
    cdef cppclass CCodec" arrow::util::Codec":
        @staticmethod
        CResult[unique_ptr[CCodec]] Create(CompressionType codec)

cdef extern from "arrow/result.h" namespace "arrow" nogil:
    cdef cppclass CResult "arrow::Result"[T]:
        pass

cdef extern from "arrow/python/common.h" namespace "arrow::py" nogil:
    T GetResultValue[T](CResult[T]) except *

Then the following Cython code:

    cdef:
        CompressionType compression_type = ...
        unique_ptr[CCodec] c_codec
    c_codec = GetResultValue(CCodec.Create(compression_type))

creates this C++ code:

  __pyx_t_6 = arrow::py::GetResultValue<std::unique_ptr< arrow::util::Codec> >( arrow::util::Codec::Create(__pyx_v_compression_type)); if (unlikely(PyErr_Occurred())) __PYX_ERR(6, 1203, __pyx_L1_error)
  __pyx_v_codec = __pyx_t_6;

which fails compiling because it tries to copy a unique_ptr.
Cython should instead move the temporary:

  __pyx_t_6 = arrow::py::GetResultValue<std::unique_ptr< arrow::util::Codec> >( arrow::util::Codec::Create(__pyx_v_compression_type)); if (unlikely(PyErr_Occurred())) __PYX_ERR(6, 1203, __pyx_L1_error)
  __pyx_v_codec = std::move(__pyx_t_6);

(I can add the move() call explicitly in the Cython source, but it's a bit surprising, and also it's also inconvenient because of #2169)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions