diff --git a/doublets/src/mem/split/generic/external_sources_recursion_less_tree.rs b/doublets/src/mem/split/generic/external_sources_recursion_less_tree.rs index 5d64276..24f92ab 100644 --- a/doublets/src/mem/split/generic/external_sources_recursion_less_tree.rs +++ b/doublets/src/mem/split/generic/external_sources_recursion_less_tree.rs @@ -197,6 +197,16 @@ impl LinksTree for ExternalSourcesRecursionlessTree { fn attach(&mut self, root: &mut T, index: T) { unsafe { NoRecurSzbTree::attach(self, root as *mut _, index) } } + + fn detach_with_mem(&mut self, _mem: NonNull<[LinkPart]>, root: &mut T, index: T) { + // Split trees don't use unit memory, so just delegate to normal detach + self.detach(root, index) + } + + fn attach_with_mem(&mut self, _mem: NonNull<[LinkPart]>, root: &mut T, index: T) { + // Split trees don't use unit memory, so just delegate to normal attach + self.attach(root, index) + } } impl SplitUpdateMem for ExternalSourcesRecursionlessTree { diff --git a/doublets/src/mem/split/generic/external_targets_recursion_less_tree.rs b/doublets/src/mem/split/generic/external_targets_recursion_less_tree.rs index a5f377d..83fa143 100644 --- a/doublets/src/mem/split/generic/external_targets_recursion_less_tree.rs +++ b/doublets/src/mem/split/generic/external_targets_recursion_less_tree.rs @@ -195,6 +195,16 @@ impl LinksTree for ExternalTargetsRecursionlessTree { fn attach(&mut self, root: &mut T, index: T) { unsafe { NoRecurSzbTree::attach(self, root as *mut _, index) } } + + fn detach_with_mem(&mut self, _mem: NonNull<[LinkPart]>, root: &mut T, index: T) { + // Split trees don't use unit memory, so just delegate to normal detach + self.detach(root, index) + } + + fn attach_with_mem(&mut self, _mem: NonNull<[LinkPart]>, root: &mut T, index: T) { + // Split trees don't use unit memory, so just delegate to normal attach + self.attach(root, index) + } } impl SplitUpdateMem for ExternalTargetsRecursionlessTree { diff --git a/doublets/src/mem/split/generic/internal_sources_recursion_less_tree.rs b/doublets/src/mem/split/generic/internal_sources_recursion_less_tree.rs index d9bd0c6..f55c517 100644 --- a/doublets/src/mem/split/generic/internal_sources_recursion_less_tree.rs +++ b/doublets/src/mem/split/generic/internal_sources_recursion_less_tree.rs @@ -129,6 +129,16 @@ impl LinksTree for InternalSourcesRecursionlessTree { fn attach(&mut self, root: &mut T, index: T) { unsafe { NoRecurSzbTree::attach(self, root as *mut _, index) } } + + fn detach_with_mem(&mut self, _mem: NonNull<[LinkPart]>, root: &mut T, index: T) { + // Split trees don't use unit memory, so just delegate to normal detach + self.detach(root, index) + } + + fn attach_with_mem(&mut self, _mem: NonNull<[LinkPart]>, root: &mut T, index: T) { + // Split trees don't use unit memory, so just delegate to normal attach + self.attach(root, index) + } } impl SplitUpdateMem for InternalSourcesRecursionlessTree { diff --git a/doublets/src/mem/split/generic/internal_targets_recursion_less_tree.rs b/doublets/src/mem/split/generic/internal_targets_recursion_less_tree.rs index f46dc4f..0a42840 100644 --- a/doublets/src/mem/split/generic/internal_targets_recursion_less_tree.rs +++ b/doublets/src/mem/split/generic/internal_targets_recursion_less_tree.rs @@ -136,6 +136,16 @@ impl LinksTree for InternalTargetsRecursionlessTree { fn attach(&mut self, root: &mut T, index: T) { unsafe { NoRecurSzbTree::attach(self, root as *mut _, index) } } + + fn detach_with_mem(&mut self, _mem: NonNull<[LinkPart]>, root: &mut T, index: T) { + // Split trees don't use unit memory, so just delegate to normal detach + self.detach(root, index) + } + + fn attach_with_mem(&mut self, _mem: NonNull<[LinkPart]>, root: &mut T, index: T) { + // Split trees don't use unit memory, so just delegate to normal attach + self.attach(root, index) + } } impl SplitUpdateMem for InternalTargetsRecursionlessTree { diff --git a/doublets/src/mem/traits.rs b/doublets/src/mem/traits.rs index dd8df6f..62e3980 100644 --- a/doublets/src/mem/traits.rs +++ b/doublets/src/mem/traits.rs @@ -16,6 +16,11 @@ pub trait LinksTree { fn detach(&mut self, root: &mut T, index: T); fn attach(&mut self, root: &mut T, index: T); + + // New methods that accept memory explicitly to avoid stacked borrows issues + fn detach_with_mem(&mut self, mem: NonNull<[LinkPart]>, root: &mut T, index: T); + + fn attach_with_mem(&mut self, mem: NonNull<[LinkPart]>, root: &mut T, index: T); } pub trait UnitUpdateMem { diff --git a/doublets/src/mem/unit/generic/sources_recursionless_size_balanced_tree.rs b/doublets/src/mem/unit/generic/sources_recursionless_size_balanced_tree.rs index 8dd920c..bc142a0 100644 --- a/doublets/src/mem/unit/generic/sources_recursionless_size_balanced_tree.rs +++ b/doublets/src/mem/unit/generic/sources_recursionless_size_balanced_tree.rs @@ -191,6 +191,22 @@ impl LinksTree for LinksSourcesRecursionlessSizeBalancedTree fn attach(&mut self, root: &mut T, index: T) { unsafe { NoRecurSzbTree::attach(self, root as *mut _, index) } } + + fn detach_with_mem(&mut self, mem: NonNull<[LinkPart]>, root: &mut T, index: T) { + // Temporarily update memory reference to avoid stacked borrows + let old_mem = self.base.mem; + self.base.mem = mem; + unsafe { NoRecurSzbTree::detach(self, root as *mut _, index) } + self.base.mem = old_mem; + } + + fn attach_with_mem(&mut self, mem: NonNull<[LinkPart]>, root: &mut T, index: T) { + // Temporarily update memory reference to avoid stacked borrows + let old_mem = self.base.mem; + self.base.mem = mem; + unsafe { NoRecurSzbTree::attach(self, root as *mut _, index) } + self.base.mem = old_mem; + } } impl UnitUpdateMem for LinksSourcesRecursionlessSizeBalancedTree { diff --git a/doublets/src/mem/unit/generic/targets_recursionless_size_balanced_tree.rs b/doublets/src/mem/unit/generic/targets_recursionless_size_balanced_tree.rs index 2867d20..557df2d 100644 --- a/doublets/src/mem/unit/generic/targets_recursionless_size_balanced_tree.rs +++ b/doublets/src/mem/unit/generic/targets_recursionless_size_balanced_tree.rs @@ -191,6 +191,22 @@ impl LinksTree for LinksTargetsRecursionlessSizeBalancedTree fn attach(&mut self, root: &mut T, index: T) { unsafe { NoRecurSzbTree::attach(self, root as *mut _, index) } } + + fn detach_with_mem(&mut self, mem: NonNull<[LinkPart]>, root: &mut T, index: T) { + // Temporarily update memory reference to avoid stacked borrows + let old_mem = self.base.mem; + self.base.mem = mem; + unsafe { NoRecurSzbTree::detach(self, root as *mut _, index) } + self.base.mem = old_mem; + } + + fn attach_with_mem(&mut self, mem: NonNull<[LinkPart]>, root: &mut T, index: T) { + // Temporarily update memory reference to avoid stacked borrows + let old_mem = self.base.mem; + self.base.mem = mem; + unsafe { NoRecurSzbTree::attach(self, root as *mut _, index) } + self.base.mem = old_mem; + } } impl UnitUpdateMem for LinksTargetsRecursionlessSizeBalancedTree { diff --git a/doublets/src/mem/unit/store.rs b/doublets/src/mem/unit/store.rs index 5231732..ef51908 100644 --- a/doublets/src/mem/unit/store.rs +++ b/doublets/src/mem/unit/store.rs @@ -151,19 +151,27 @@ impl>, TS: UnitTree, TT: UnitTree, TU: } unsafe fn detach_source_unchecked(&mut self, root: *mut T, index: T) { - self.sources.detach(&mut *root, index); + // Get memory pointer first to avoid overlapping borrows + let mem_ptr = self.mem_ptr; + self.sources.detach_with_mem(mem_ptr, &mut *root, index); } unsafe fn detach_target_unchecked(&mut self, root: *mut T, index: T) { - self.targets.detach(&mut *root, index); + // Get memory pointer first to avoid overlapping borrows + let mem_ptr = self.mem_ptr; + self.targets.detach_with_mem(mem_ptr, &mut *root, index); } unsafe fn attach_source_unchecked(&mut self, root: *mut T, index: T) { - self.sources.attach(&mut *root, index); + // Get memory pointer first to avoid overlapping borrows + let mem_ptr = self.mem_ptr; + self.sources.attach_with_mem(mem_ptr, &mut *root, index); } unsafe fn attach_target_unchecked(&mut self, root: *mut T, index: T) { - self.targets.attach(&mut *root, index); + // Get memory pointer first to avoid overlapping borrows + let mem_ptr = self.mem_ptr; + self.targets.attach_with_mem(mem_ptr, &mut *root, index); } unsafe fn detach_source(&mut self, index: T) {