@@ -17,14 +17,34 @@ use crate::{
1717use malachite_bigint:: { BigInt , ToBigInt } ;
1818use num_traits:: { One , Signed , Zero } ;
1919
20- #[ pyclass( module = false , name = "slice" , unhashable = true , traverse) ]
20+ #[ pyclass( module = false , name = "slice" , unhashable = true , traverse = "manual" ) ]
2121#[ derive( Debug ) ]
2222pub struct PySlice {
2323 pub start : Option < PyObjectRef > ,
2424 pub stop : PyObjectRef ,
2525 pub step : Option < PyObjectRef > ,
2626}
2727
28+ // SAFETY: Traverse properly visits all owned PyObjectRefs
29+ unsafe impl crate :: object:: Traverse for PySlice {
30+ fn traverse ( & self , traverse_fn : & mut crate :: object:: TraverseFn < ' _ > ) {
31+ self . start . traverse ( traverse_fn) ;
32+ self . stop . traverse ( traverse_fn) ;
33+ self . step . traverse ( traverse_fn) ;
34+ }
35+
36+ fn clear ( & mut self , out : & mut Vec < PyObjectRef > ) {
37+ if let Some ( start) = self . start . take ( ) {
38+ out. push ( start) ;
39+ }
40+ // stop is not Option, so it will be freed when payload is dropped
41+ // (via drop_in_place on freelist pop, or Box::from_raw on dealloc)
42+ if let Some ( step) = self . step . take ( ) {
43+ out. push ( step) ;
44+ }
45+ }
46+ }
47+
2848thread_local ! {
2949 static SLICE_FREELIST : Cell <crate :: object:: FreeList <PySlice >> = const { Cell :: new( crate :: object:: FreeList :: new( ) ) } ;
3050}
0 commit comments