@@ -56,48 +56,33 @@ fn list_from<T: Clone>(v: &[T]) -> LinkedList<T> {
56
56
v. iter ( ) . cloned ( ) . collect ( )
57
57
}
58
58
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.
59
62
fn check_links < T > ( list : & LinkedList < T > ) {
60
- unsafe {
61
- let mut len = 0 ;
62
- let mut last_ptr: Option < & Node < T > > = None ;
63
- let mut node_ptr: & Node < T > ;
64
- match list. head {
65
- None => {
66
- // tail node should also be None.
67
- assert ! ( list. tail. is_none( ) ) ;
68
- assert_eq ! ( 0 , list. len) ;
69
- return ;
70
- }
71
- Some ( node) => node_ptr = & * node. as_ptr ( ) ,
72
- }
73
- loop {
74
- match ( last_ptr, node_ptr. prev ) {
75
- ( None , None ) => { }
76
- ( None , _) => panic ! ( "prev link for head" ) ,
77
- ( Some ( p) , Some ( pptr) ) => {
78
- assert_eq ! ( p as * const Node <T >, pptr. as_ptr( ) as * const Node <T >) ;
79
- }
80
- _ => panic ! ( "prev link is none, not good" ) ,
81
- }
82
- match node_ptr. next {
83
- Some ( next) => {
84
- last_ptr = Some ( node_ptr) ;
85
- node_ptr = & * next. as_ptr ( ) ;
86
- len += 1 ;
87
- }
88
- None => {
89
- len += 1 ;
90
- break ;
91
- }
92
- }
93
- }
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
+ } ;
94
71
95
- // verify that the tail node points to the last node.
96
- let tail = list. tail . as_ref ( ) . expect ( "some tail node" ) . as_ref ( ) ;
97
- assert_eq ! ( tail as * const Node <T >, node_ptr as * const Node <T >) ;
98
- // check that len matches interior links.
99
- assert_eq ! ( len, list. len) ;
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" ) ;
100
81
}
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" ) ;
101
86
}
102
87
103
88
#[ test]
@@ -1027,7 +1012,7 @@ fn extract_if_drop_panic_leak() {
1027
1012
1028
1013
macro_rules! struct_with_counted_drop {
1029
1014
( $struct_name: ident$( ( $elt_ty: ty) ) ?, $drop_counter: ident $( => $drop_stmt: expr) ?) => {
1030
- thread_local! { static $drop_counter: Cell <i32 > = Cell :: new( 0 ) ; }
1015
+ thread_local! { static $drop_counter: Cell <u32 > = Cell :: new( 0 ) ; }
1031
1016
1032
1017
struct $struct_name$( ( $elt_ty) ) ?;
1033
1018
0 commit comments