rust-cpython: remove useless Option<$leaked> from py_shared_iterator
authorYuya Nishihara <yuya@tcha.org>
Sat, 12 Oct 2019 20:48:30 +0900
changeset 43426 6f9f15a476a4
parent 43425 ed50f2c31a4c
child 43427 b7ab3a0a9e57
rust-cpython: remove useless Option<$leaked> from py_shared_iterator We no longer need to carefully drop the iterator when it's consumed. Mutation is allowed even if the iterator exists. There's a minor behavior change: next(iter) may return/raise something other than StopIteration if it's called after the iterator has been fully consumed, and if the Rust object isn't a FusedIterator.
rust/hg-cpython/src/ref_sharing.rs
--- a/rust/hg-cpython/src/ref_sharing.rs	Sat Oct 12 20:26:38 2019 +0900
+++ b/rust/hg-cpython/src/ref_sharing.rs	Sat Oct 12 20:48:30 2019 +0900
@@ -570,25 +570,14 @@
         $success_type: ty
     ) => {
         py_class!(pub class $name |py| {
-            data inner: RefCell<Option<$leaked>>;
+            data inner: RefCell<$leaked>;
 
             def __next__(&self) -> PyResult<$success_type> {
-                let mut inner_opt = self.inner(py).borrow_mut();
-                if let Some(leaked) = inner_opt.as_mut() {
-                    let mut iter = leaked.try_borrow_mut(py)?;
-                    match iter.next() {
-                        None => {
-                            drop(iter);
-                            // replace Some(inner) by None, drop $leaked
-                            inner_opt.take();
-                            Ok(None)
-                        }
-                        Some(res) => {
-                            $success_func(py, res)
-                        }
-                    }
-                } else {
-                    Ok(None)
+                let mut leaked = self.inner(py).borrow_mut();
+                let mut iter = leaked.try_borrow_mut(py)?;
+                match iter.next() {
+                    None => Ok(None),
+                    Some(res) => $success_func(py, res),
                 }
             }
 
@@ -604,7 +593,7 @@
             ) -> PyResult<Self> {
                 Self::create_instance(
                     py,
-                    RefCell::new(Some(leaked)),
+                    RefCell::new(leaked),
                 )
             }
         }