Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7a2678d

Browse files
Add invariant to VecDeque::pop_* that len < cap if pop successful
Similar to #114370 for VecDeque instead of Vec. It now uses `core::hint::assert_unchecked`.
1 parent 7a495cc commit 7a2678d

File tree

2 files changed

+75
-2
lines changed

2 files changed

+75
-2
lines changed

‎library/alloc/src/collections/vec_deque/mod.rs‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,7 +1614,10 @@ impl<T, A: Allocator> VecDeque<T, A> {
16141614
let old_head = self.head;
16151615
self.head = self.to_physical_idx(1);
16161616
self.len -= 1;
1617-
Some(unsafe { self.buffer_read(old_head) })
1617+
unsafe {
1618+
core::hint::assert_unchecked(self.len < self.capacity());
1619+
Some(self.buffer_read(old_head))
1620+
}
16181621
}
16191622
}
16201623

@@ -1638,7 +1641,10 @@ impl<T, A: Allocator> VecDeque<T, A> {
16381641
None
16391642
} else {
16401643
self.len -= 1;
1641-
Some(unsafe { self.buffer_read(self.to_physical_idx(self.len)) })
1644+
unsafe {
1645+
core::hint::assert_unchecked(self.len < self.capacity());
1646+
Some(self.buffer_read(self.to_physical_idx(self.len)))
1647+
}
16421648
}
16431649
}
16441650

‎tests/codegen/vecdeque_pop_push.rs‎

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//@ compile-flags: -O
2+
3+
#![crate_type = "lib"]
4+
5+
use std::collections::VecDeque;
6+
7+
#[no_mangle]
8+
// CHECK-LABEL: @noop_back(
9+
pub fn noop_back(v: &mut VecDeque<u8>) {
10+
// CHECK-NOT: grow
11+
// CHECK: tail call void @llvm.assume
12+
// CHECK-NOT: grow
13+
// CHECK: ret
14+
if let Some(x) = v.pop_back() {
15+
v.push_back(x);
16+
}
17+
}
18+
19+
#[no_mangle]
20+
// CHECK-LABEL: @noop_front(
21+
pub fn noop_front(v: &mut VecDeque<u8>) {
22+
// CHECK-NOT: grow
23+
// CHECK: tail call void @llvm.assume
24+
// CHECK-NOT: grow
25+
// CHECK: ret
26+
if let Some(x) = v.pop_front() {
27+
v.push_front(x);
28+
}
29+
}
30+
31+
#[no_mangle]
32+
// CHECK-LABEL: @move_byte_front_to_back(
33+
pub fn move_byte_front_to_back(v: &mut VecDeque<u8>) {
34+
// CHECK-NOT: grow
35+
// CHECK: tail call void @llvm.assume
36+
// CHECK-NOT: grow
37+
// CHECK: ret
38+
if let Some(x) = v.pop_front() {
39+
v.push_back(x);
40+
}
41+
}
42+
43+
#[no_mangle]
44+
// CHECK-LABEL: @move_byte_back_to_front(
45+
pub fn move_byte_back_to_front(v: &mut VecDeque<u8>) {
46+
// CHECK-NOT: grow
47+
// CHECK: tail call void @llvm.assume
48+
// CHECK-NOT: grow
49+
// CHECK: ret
50+
if let Some(x) = v.pop_back() {
51+
v.push_front(x);
52+
}
53+
}
54+
55+
#[no_mangle]
56+
// CHECK-LABEL: @push_back_byte(
57+
pub fn push_back_byte(v: &mut VecDeque<u8>) {
58+
// CHECK: call {{.*}}grow
59+
v.push_back(3);
60+
}
61+
62+
#[no_mangle]
63+
// CHECK-LABEL: @push_front_byte(
64+
pub fn push_front_byte(v: &mut VecDeque<u8>) {
65+
// CHECK: call {{.*}}grow
66+
v.push_front(3);
67+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /