Skip to content

Commit 8f888b8

Browse files
authored
Unrolled build for #142520
Rollup merge of #142520 - hkBst:less-static-mut, r=tgross35 alloc: less static mut + some cleanup I'm looking into #125035 and would like some feedback on my approach.
2 parents 27eb269 + 2d3a37d commit 8f888b8

File tree

1 file changed

+55
-106
lines changed
  • library/alloc/src/collections/linked_list

1 file changed

+55
-106
lines changed

library/alloc/src/collections/linked_list/tests.rs

Lines changed: 55 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
2-
#![allow(static_mut_refs)]
3-
1+
use std::cell::Cell;
42
use std::panic::{AssertUnwindSafe, catch_unwind};
53
use std::thread;
64

@@ -58,48 +56,33 @@ fn list_from<T: Clone>(v: &[T]) -> LinkedList<T> {
5856
v.iter().cloned().collect()
5957
}
6058

59+
/// Starting from the head of the LinkedList,
60+
/// follow the next links, while checking the prev links,
61+
/// and check that length equals the count of visited nodes.
6162
fn check_links<T>(list: &LinkedList<T>) {
62-
unsafe {
63-
let mut len = 0;
64-
let mut last_ptr: Option<&Node<T>> = None;
65-
let mut node_ptr: &Node<T>;
66-
match list.head {
67-
None => {
68-
// tail node should also be None.
69-
assert!(list.tail.is_none());
70-
assert_eq!(0, list.len);
71-
return;
72-
}
73-
Some(node) => node_ptr = &*node.as_ptr(),
74-
}
75-
loop {
76-
match (last_ptr, node_ptr.prev) {
77-
(None, None) => {}
78-
(None, _) => panic!("prev link for head"),
79-
(Some(p), Some(pptr)) => {
80-
assert_eq!(p as *const Node<T>, pptr.as_ptr() as *const Node<T>);
81-
}
82-
_ => panic!("prev link is none, not good"),
83-
}
84-
match node_ptr.next {
85-
Some(next) => {
86-
last_ptr = Some(node_ptr);
87-
node_ptr = &*next.as_ptr();
88-
len += 1;
89-
}
90-
None => {
91-
len += 1;
92-
break;
93-
}
94-
}
95-
}
96-
97-
// verify that the tail node points to the last node.
98-
let tail = list.tail.as_ref().expect("some tail node").as_ref();
99-
assert_eq!(tail as *const Node<T>, node_ptr as *const Node<T>);
100-
// check that len matches interior links.
101-
assert_eq!(len, list.len);
63+
let mut node: &Node<T> = if let Some(node) = list.head {
64+
// SAFETY: depends on correctness of LinkedList
65+
unsafe { &*node.as_ptr() }
66+
} else {
67+
assert!(list.tail.is_none(), "empty list should have no tail node");
68+
assert_eq!(list.len, 0, "empty list should have length 0");
69+
return;
70+
};
71+
72+
assert!(node.prev.is_none(), "head node should not have a prev link");
73+
let mut prev;
74+
let mut len = 1;
75+
while let Some(next) = node.next {
76+
prev = node;
77+
// SAFETY: depends on correctness of LinkedList
78+
node = unsafe { &*next.as_ptr() };
79+
len += 1;
80+
assert_eq!(node.prev.expect("missing prev link"), prev.into(), "bad prev link");
10281
}
82+
83+
let tail = list.tail.expect("list is non-empty, so there should be a tail node");
84+
assert_eq!(tail, node.into(), "tail node points to the last node");
85+
assert_eq!(len, list.len, "len matches interior links");
10386
}
10487

10588
#[test]
@@ -1027,21 +1010,26 @@ fn extract_if_drop_panic_leak() {
10271010
assert_eq!(d7.dropped(), 1);
10281011
}
10291012

1030-
#[test]
1031-
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
1032-
fn extract_if_pred_panic_leak() {
1033-
static mut DROPS: i32 = 0;
1013+
macro_rules! struct_with_counted_drop {
1014+
($struct_name:ident$(($elt_ty:ty))?, $drop_counter:ident $(=> $drop_stmt:expr)?) => {
1015+
thread_local! {static $drop_counter: Cell<u32> = Cell::new(0);}
1016+
1017+
struct $struct_name$(($elt_ty))?;
10341018

1035-
#[derive(Debug)]
1036-
struct D(u32);
1019+
impl Drop for $struct_name {
1020+
fn drop(&mut self) {
1021+
$drop_counter.set($drop_counter.get() + 1);
10371022

1038-
impl Drop for D {
1039-
fn drop(&mut self) {
1040-
unsafe {
1041-
DROPS += 1;
1023+
$($drop_stmt(self))?
10421024
}
10431025
}
1044-
}
1026+
};
1027+
}
1028+
1029+
#[test]
1030+
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
1031+
fn extract_if_pred_panic_leak() {
1032+
struct_with_counted_drop!(D(u32), DROPS);
10451033

10461034
let mut q = LinkedList::new();
10471035
q.push_back(D(3));
@@ -1053,26 +1041,17 @@ fn extract_if_pred_panic_leak() {
10531041
q.push_front(D(1));
10541042
q.push_front(D(0));
10551043

1056-
catch_unwind(AssertUnwindSafe(|| {
1044+
_ = catch_unwind(AssertUnwindSafe(|| {
10571045
q.extract_if(|item| if item.0 >= 2 { panic!() } else { true }).for_each(drop)
1058-
}))
1059-
.ok();
1046+
}));
10601047

1061-
assert_eq!(unsafe { DROPS }, 2); // 0 and 1
1048+
assert_eq!(DROPS.get(), 2); // 0 and 1
10621049
assert_eq!(q.len(), 6);
10631050
}
10641051

10651052
#[test]
10661053
fn test_drop() {
1067-
static mut DROPS: i32 = 0;
1068-
struct Elem;
1069-
impl Drop for Elem {
1070-
fn drop(&mut self) {
1071-
unsafe {
1072-
DROPS += 1;
1073-
}
1074-
}
1075-
}
1054+
struct_with_counted_drop!(Elem, DROPS);
10761055

10771056
let mut ring = LinkedList::new();
10781057
ring.push_back(Elem);
@@ -1081,20 +1060,12 @@ fn test_drop() {
10811060
ring.push_front(Elem);
10821061
drop(ring);
10831062

1084-
assert_eq!(unsafe { DROPS }, 4);
1063+
assert_eq!(DROPS.get(), 4);
10851064
}
10861065

10871066
#[test]
10881067
fn test_drop_with_pop() {
1089-
static mut DROPS: i32 = 0;
1090-
struct Elem;
1091-
impl Drop for Elem {
1092-
fn drop(&mut self) {
1093-
unsafe {
1094-
DROPS += 1;
1095-
}
1096-
}
1097-
}
1068+
struct_with_counted_drop!(Elem, DROPS);
10981069

10991070
let mut ring = LinkedList::new();
11001071
ring.push_back(Elem);
@@ -1104,54 +1075,32 @@ fn test_drop_with_pop() {
11041075

11051076
drop(ring.pop_back());
11061077
drop(ring.pop_front());
1107-
assert_eq!(unsafe { DROPS }, 2);
1078+
assert_eq!(DROPS.get(), 2);
11081079

11091080
drop(ring);
1110-
assert_eq!(unsafe { DROPS }, 4);
1081+
assert_eq!(DROPS.get(), 4);
11111082
}
11121083

11131084
#[test]
11141085
fn test_drop_clear() {
1115-
static mut DROPS: i32 = 0;
1116-
struct Elem;
1117-
impl Drop for Elem {
1118-
fn drop(&mut self) {
1119-
unsafe {
1120-
DROPS += 1;
1121-
}
1122-
}
1123-
}
1086+
struct_with_counted_drop!(Elem, DROPS);
11241087

11251088
let mut ring = LinkedList::new();
11261089
ring.push_back(Elem);
11271090
ring.push_front(Elem);
11281091
ring.push_back(Elem);
11291092
ring.push_front(Elem);
11301093
ring.clear();
1131-
assert_eq!(unsafe { DROPS }, 4);
1094+
assert_eq!(DROPS.get(), 4);
11321095

11331096
drop(ring);
1134-
assert_eq!(unsafe { DROPS }, 4);
1097+
assert_eq!(DROPS.get(), 4);
11351098
}
11361099

11371100
#[test]
11381101
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
11391102
fn test_drop_panic() {
1140-
static mut DROPS: i32 = 0;
1141-
1142-
struct D(bool);
1143-
1144-
impl Drop for D {
1145-
fn drop(&mut self) {
1146-
unsafe {
1147-
DROPS += 1;
1148-
}
1149-
1150-
if self.0 {
1151-
panic!("panic in `drop`");
1152-
}
1153-
}
1154-
}
1103+
struct_with_counted_drop!(D(bool), DROPS => |this: &D| if this.0 { panic!("panic in `drop`"); } );
11551104

11561105
let mut q = LinkedList::new();
11571106
q.push_back(D(false));
@@ -1165,7 +1114,7 @@ fn test_drop_panic() {
11651114

11661115
catch_unwind(move || drop(q)).ok();
11671116

1168-
assert_eq!(unsafe { DROPS }, 8);
1117+
assert_eq!(DROPS.get(), 8);
11691118
}
11701119

11711120
#[test]

0 commit comments

Comments
 (0)