-
Notifications
You must be signed in to change notification settings - Fork 904
Description
This is mainly an internal issue, but it has to be decided before we stabilize IntoPyObject, because after that it will be a breaking change.
I request that we remove the following impl:
Lines 617 to 639 in 2f5b45e
| impl<'a, 'py, T> BoundObject<'py, T> for &'a Bound<'py, T> { | |
| type Any = &'a Bound<'py, PyAny>; | |
| fn as_borrowed(&self) -> Borrowed<'a, 'py, T> { | |
| Bound::as_borrowed(self) | |
| } | |
| fn into_bound(self) -> Bound<'py, T> { | |
| self.clone() | |
| } | |
| fn into_any(self) -> Self::Any { | |
| self.as_any() | |
| } | |
| fn into_ptr(self) -> *mut ffi::PyObject { | |
| self.clone().into_ptr() | |
| } | |
| fn unbind(self) -> Py<T> { | |
| self.clone().unbind() | |
| } | |
| } |
And replace all places where IntoPyObject<Output = &Bound> with Output = Borrowed.
For users, this will be a transparent change, since Borrowed derefs to Bound. So why do I want this?
Borrowed has a feature &Bound doesn't have: it is layout-compatible with *mut ffi::PyObject (and so is Bound). What that means is that a container, for example a Vec, of Borrowed can be treated as *mut *mut ffi::PyObject (an array of *mut ffi::PyObject) for the purposes of FFI.
This may sound unimportant, but this can enable speedups. For example, the pycall!() macro I'm experimenting with, we can unpack any set of objects. Internally, if the number of entries is not constant (in which case we use a stack array), the macro allocates a Vec and fills it with the values. For convenience, the macro accepts any value that is IntoPyObject.
Ideally, we will construct one Vec, and use it to store all arguments. And we need to store them twice: once because they may be Bounds and need dropping, and the other as *mut ffi::PyObject to pass to the C FFI. Ideally, these two will collapse, and we will use one Vec for both for all arguments.
There is one obstacle for that: this impl. with this impl, we cannot take IntoPyObject::Output and treat it as *mut ffi::PyObject, because it may be a &Bound, which is actually *const *mut ffi::PyObject. That forces us to use two or more Vecs when one is enough.
It can be worked around by complicating BoundObject more (adding another fn and associated type for "if this is a &Bound convert it to Borrowed), but given the little utility of this impl, I suggest we just remove it.