Skip to content

Fix bug in split_before and split_after for first and last node edge cases - #19

Open
morlinbrot wants to merge 2 commits into
contain-rs:masterfrom
morlinbrot:master
Open

Fix bug in split_before and split_after for first and last node edge cases#19
morlinbrot wants to merge 2 commits into
contain-rs:masterfrom
morlinbrot:master

Conversation

@morlinbrot

Copy link
Copy Markdown

Fixes #18

The split_before and split_after methods don't handle the edge case of being at the first or last node correctly.

Example split_before:
In the current implementation, output_front will be set to the list's head before checking if there actually is a node before where the cursor currently is, which in the case of being at the first node will not be the case. In this case, we want to return an empty list which can be done by simply not setting a new head.

I tried to implement a fix as unobtrusive to the original implementation as possible, since I assume that the methods are written with readability in mind for the too-many-lists project. In my implementation, I wrote the methods a bit more "cleverly" which may be not as easy to follow but shorter and more focused on all the edge cases that need to be covered, here's a snippet of it:

pub fn split_before(&mut self) -> LinkedList<T> {
    match self.idx {
        None => mem::replace(self.list, LinkedList::new()),
        Some(0) => LinkedList::new(),
        Some(idx) => unsafe {
            let cur = self.cur.unwrap();
            let out_head = self.list.head;
            let out_tail = (*cur.as_ptr()).prev.take();

            if let Some(node) = out_tail {
                (*node.as_ptr()).next = None;
            }

            let old_len = self.list.len;
            let new_len = old_len - idx;

            self.list.head = Some(cur);
            self.list.len = new_len;
            self.idx = Some(0);

            LinkedList {
                head: out_head,
                tail: out_tail,
                len: old_len - new_len,
                _marker: PhantomData,
            }
        },
    }
}

Let me know if you'd be interested in switching to my implementation, I'd be glad to update the PR.

@morlinbrot

Copy link
Copy Markdown
Author

Note the differences in implementation between this and the same fix over at too-many-lists.

@alexkudryavtsev88

alexkudryavtsev88 commented May 11, 2024

Copy link
Copy Markdown

I've checked your new solution - it looks like all stuff works fine:

  • cursor.split_before() after first cursor.move_next() returns empty list, the source list stays in initial state;
  • also, there is no more attempt to subtract with overflow panic at pop_front that's called upon the list drop (this issue was present in "book" implementation)

@pczarn

pczarn commented Dec 2, 2024

Copy link
Copy Markdown
Contributor

I'll look into this

@morlinbrot

Copy link
Copy Markdown
Author

Just rebased this to solve the merge conflicts. @pczarn, if you have the time, I'd love for you to have another look.

Comment thread src/lib.rs Outdated
@pczarn

pczarn commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

I did. Just need to fix those 1.67 and 1.68 and we release it.

Co-authored-by: Peter Blackson <pioczarn@gmail.com>
@morlinbrot

morlinbrot commented Sep 3, 2026

Copy link
Copy Markdown
Author

I did. Just need to fix those 1.67 and 1.68 and we release it.

Thanks. From your wording I can't tell, do you want me to fix the CI issues or are you looking into it?

The issues arise from serde_json having increased their MSRV (this lib's serde_json = "1.0" dependency resolves to 1.0.151 which has the higher MSRV). I tried pinning serde_json to when it last supported Rust 1.67.0 but that causes its zmij transitive dependency to also fail. zmij doesn't have a version that supports 1.67.0.

Simplest solution would be to increase this lib's MSRV, is this something you'd consider? I'd be happy to create a separate PR for that if you want.

@pczarn

pczarn commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

On a second thought, I will do it myself and yours will get automatically rebased on top of my changes to the CI because we need an aggregate success CI job.

@pczarn

pczarn commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Github's repo settings do not seem to play nice with our renaming of CI jobs when msrv gets bumped.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: split_before and split_after return malformed list when cursor is at first or last node

3 participants