use super::*; pub(super) struct List(Option); impl List { pub(super) fn make( size: usize, tail: Option, ) -> Self where L: NewLink, { (0 .. size).fold(Self(tail), |acc, _| Self(Some(L::new(acc)))) } } impl DeepSafeDrop for List { fn take_child_at_index_0(&mut self) -> Option { self.0.take() } fn set_parent_at_index_0( &mut self, parent: L, ) -> SetParent { if let Some(child) = self.0.take() { self.0 = Some(parent); SetParent::YesReplacedChild { child0: child } } else { SetParent::No { returned_parent: parent } } } fn take_next_child_at_pos_index(&mut self) -> Option { None } } const LIST_LEN: usize = TREE_SIZE; #[test] fn no_stack_overflow() { struct ListBox(Box>); impl NewLink> for ListBox { fn new(list: List) -> Self { Self(Box::new(list)) } } impl Link> for ListBox { fn get_mut(&mut self) -> &mut List { &mut self.0 } } /// Comment-out to cause stack overflow. impl Drop for ListBox { fn drop(&mut self) { deep_safe_drop::, Self, List>(&mut *self.0); } } let list = List::::make(LIST_LEN, None); drop(list); } #[test] #[ignore] fn stack_overflow() { struct ListBox(#[allow(dead_code)] Box>); impl NewLink> for ListBox { fn new(list: List) -> Self { Self(Box::new(list)) } } let list = List::::make(LIST_LEN, None); drop(list); }