Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 14.2k
Description
When using linked_list::CursorMut, calling pop_front while the cursor is positioned at the front node does not update the index correctly. After popping the front element, I expect the index to reflect the new position of the current element, but instead it remains unchanged or becomes inconsistent.
example 1
#![feature(linked_list_cursors)]use std::collections::LinkedList;fnmain(){letmut l = LinkedList::from_iter([0,1,2]);letmut c = l.cursor_front_mut(); c.move_next();println!("index:{:?} current:{:?}", c.index(), c.current());// index: Some(1), current: Some(1)// index is decremented since we removed an item before the current one c.pop_front();println!("index:{:?} current:{:?}", c.index(), c.current());// index: Some(0), current: Some(1)// Unexpected behavior: current is at the front, but index is incremented c.pop_front();println!("index:{:?} current:{:?}", c.index(), c.current());// index: Some(1), current: Some(2), but expected index: Some(0)}minimal reproduction
#![feature(linked_list_cursors)]use std::collections::LinkedList;fnmain(){letmut l = LinkedList::from_iter([0,1]);letmut c = l.cursor_front_mut();println!("index:{:?} current:{:?}", c.index(), c.current());// index: Some(0), current: Some(0)// Unexpected behavior: after removing the front (which is also current), index goes at 1 c.pop_front();println!("index:{:?} current:{:?}", c.index(), c.current());// index: Some(1), current: Some(1), but expected index: Some(0)}link to playground: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=aa3317b89922e9ed623525807c8b90c2
Expected Behavior
When popping the front element and the cursor's current element becomes the new front, index() should return Some(0).
Current Behavior
index() returns a wrong index value (Some(1) in these examples), which is misleading because the cursor is now logically positioned at the new front.
Meta
rustc +nightly --version --verbose:
rustc 1.92.0-nightly (be0ade2b6 2025-10-11) binary: rustc commit-hash: be0ade2b602bdfe37a3cc259fcc79e8624dcba94 commit-date: 2025-10-11 host: x86_64-unknown-linux-gnu release: 1.92.0-nightly LLVM version: 21.1.2 Proposed Change
The current code: https://github.com/rust-lang/rust/blob/ff6dc928c5e33ce8e65c6911a790b9efcb5ef53a/library/alloc/src/collections/linked_list.rs#L1845C5-L1864C6
My change proposal:
#[unstable(feature = "linked_list_cursors", issue = "58533")]pubfnpop_front(&mutself) -> Option<T>{// We can't check if current is empty, we must check the list directly.// It is possible for `self.current == None` and the list to be// non-empty.ifself.list.is_empty(){None}else{// We can't point to the node that we pop. Copying the behavior of// `remove_current`, we move on to the next node in the sequence.// If the list is of length 1 then we end pointing to the "ghost"// node at index 0, which is expected.ifself.list.head == self.current{self.move_next();}self.index = self.index.saturating_sub(1);self.list.pop_front()}}If this issue makes sense and the expected behavior above is correct, I’d be happy to open a pull request with the fix.
Thank you for the amazing work you all do on Rust