diff -r 8db8fa1de2ef -r 8f549c46bc64 rust/hg-cpython/src/ref_sharing.rs --- a/rust/hg-cpython/src/ref_sharing.rs Sun Sep 01 17:37:30 2019 +0900 +++ b/rust/hg-cpython/src/ref_sharing.rs Sun Sep 01 17:48:24 2019 +0900 @@ -216,14 +216,24 @@ .borrow_mut(py, unsafe { data.borrow_mut() }) } + /// Returns a leaked reference and its management object. + /// + /// # Safety + /// + /// It's up to you to make sure that the management object lives + /// longer than the leaked reference. Otherwise, you'll get a + /// dangling reference. fn leak_immutable<'a>( &'a self, py: Python<'a>, - ) -> PyResult<&'static $inner_struct> { + ) -> PyResult<($leaked, &'static $inner_struct)> { // assert $data_member type use crate::ref_sharing::PySharedRefCell; let data: &PySharedRefCell<_> = self.$data_member(py); - self.py_shared_state(py).leak_immutable(py, data) + let static_ref = + self.py_shared_state(py).leak_immutable(py, data)?; + let leak_handle = $leaked::new(py, self); + Ok((leak_handle, static_ref)) } } @@ -336,10 +346,11 @@ /// data py_shared_state: PySharedState; /// /// def __iter__(&self) -> PyResult { +/// let (leak_handle, leaked_ref) = self.leak_immutable(py)?; /// MyTypeItemsIterator::create_instance( /// py, -/// RefCell::new(Some(MyTypeLeakedRef::new(py, &self))), -/// RefCell::new(self.leak_immutable(py).iter()), +/// RefCell::new(Some(leak_handle)), +/// RefCell::new(leaked_ref.iter()), /// ) /// } /// });