Skip to content

Commit

Permalink
Add invariant to VecDeque::pop_* that len < cap if pop successful
Browse files Browse the repository at this point in the history
Similar to #114370 for VecDeque instead of Vec.
  • Loading branch information
Philippe-Cholet committed Mar 26, 2024
1 parent 73476d4 commit 48431f9
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
2 changes: 2 additions & 0 deletions library/alloc/src/collections/vec_deque/mod.rs
Expand Up @@ -1614,6 +1614,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
let old_head = self.head;
self.head = self.to_physical_idx(1);
self.len -= 1;
unsafe { core::intrinsics::assume(self.len < self.capacity()); }
Some(unsafe { self.buffer_read(old_head) })
}
}
Expand All @@ -1638,6 +1639,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
None
} else {
self.len -= 1;
unsafe { core::intrinsics::assume(self.len < self.capacity()); }
Some(unsafe { self.buffer_read(self.to_physical_idx(self.len)) })
}
}
Expand Down
75 changes: 75 additions & 0 deletions tests/codegen/vecdeque_pop_push.rs
@@ -0,0 +1,75 @@
//@ compile-flags: -O

#![crate_type = "lib"]

use std::collections::VecDeque;

#[no_mangle]
// CHECK-LABEL: @noop_back(
pub fn noop_back(v: &mut VecDeque<u8>) {
// CHECK-NOT: reserve_for_push
// CHECK-NOT: call
// CHECK: tail call void @llvm.assume
// CHECK-NOT: reserve_for_push
// CHECK-NOT: call
// CHECK: ret
if let Some(x) = v.pop_back() {
v.push_back(x);
}
}

#[no_mangle]
// CHECK-LABEL: @noop_front(
pub fn noop_front(v: &mut VecDeque<u8>) {
// CHECK-NOT: reserve_for_push
// CHECK-NOT: call
// CHECK: tail call void @llvm.assume
// CHECK-NOT: reserve_for_push
// CHECK-NOT: call
// CHECK: ret
if let Some(x) = v.pop_front() {
v.push_front(x);
}
}

#[no_mangle]
// CHECK-LABEL: @move_byte_front_to_back(
pub fn move_byte_front_to_back(v: &mut VecDeque<u8>) {
// CHECK-NOT: reserve_for_push
// CHECK-NOT: call
// CHECK: tail call void @llvm.assume
// CHECK-NOT: reserve_for_push
// CHECK-NOT: call
// CHECK: ret
if let Some(x) = v.pop_front() {
v.push_back(x);
}
}

#[no_mangle]
// CHECK-LABEL: @move_byte_back_to_front(
pub fn move_byte_back_to_front(v: &mut VecDeque<u8>) {
// CHECK-NOT: reserve_for_push
// CHECK-NOT: call
// CHECK: tail call void @llvm.assume
// CHECK-NOT: reserve_for_push
// CHECK-NOT: call
// CHECK: ret
if let Some(x) = v.pop_back() {
v.push_front(x);
}
}

#[no_mangle]
// CHECK-LABEL: @push_back_byte(
pub fn push_back_byte(v: &mut VecDeque<u8>) {
// CHECK: call {{.*}}reserve_for_push
v.push_back(3);
}

#[no_mangle]
// CHECK-LABEL: @push_front_byte(
pub fn push_front_byte(v: &mut VecDeque<u8>) {
// CHECK: call {{.*}}reserve_for_push
v.push_front(3);
}

0 comments on commit 48431f9

Please sign in to comment.