1
+ use core:: intrinsics;
2
+ use core:: mem;
1
3
use core:: ptr;
2
4
3
5
use super :: node:: { marker, ForceResult :: * , Handle , NodeRef } ;
@@ -79,16 +81,24 @@ def_next_kv_uncheched_dealloc! {unsafe fn next_kv_unchecked_dealloc: right_kv}
79
81
def_next_kv_uncheched_dealloc ! { unsafe fn next_back_kv_unchecked_dealloc: left_kv}
80
82
81
83
/// This replaces the value behind the `v` unique reference by calling the
82
- /// relevant function.
84
+ /// relevant function, and returns a result obtained along the way .
83
85
///
84
- /// Safety: The change closure must not panic .
86
+ /// If a panic occurs in the ` change` closure, the entire process will be aborted .
85
87
#[ inline]
86
- unsafe fn replace < T , R > ( v : & mut T , change : impl FnOnce ( T ) -> ( T , R ) ) -> R {
88
+ fn replace < T , R > ( v : & mut T , change : impl FnOnce ( T ) -> ( T , R ) ) -> R {
89
+ struct PanicGuard ;
90
+ impl Drop for PanicGuard {
91
+ fn drop ( & mut self ) {
92
+ intrinsics:: abort ( )
93
+ }
94
+ }
95
+ let guard = PanicGuard ;
87
96
let value = unsafe { ptr:: read ( v) } ;
88
97
let ( new_value, ret) = change ( value) ;
89
98
unsafe {
90
99
ptr:: write ( v, new_value) ;
91
100
}
101
+ mem:: forget ( guard) ;
92
102
ret
93
103
}
94
104
@@ -97,26 +107,22 @@ impl<'a, K, V> Handle<NodeRef<marker::Immut<'a>, K, V, marker::Leaf>, marker::Ed
97
107
/// key and value in between.
98
108
/// Unsafe because the caller must ensure that the leaf edge is not the last one in the tree.
99
109
pub unsafe fn next_unchecked ( & mut self ) -> ( & ' a K , & ' a V ) {
100
- unsafe {
101
- replace ( self , |leaf_edge| {
102
- let kv = leaf_edge. next_kv ( ) ;
103
- let kv = unwrap_unchecked ( kv. ok ( ) ) ;
104
- ( kv. next_leaf_edge ( ) , kv. into_kv ( ) )
105
- } )
106
- }
110
+ replace ( self , |leaf_edge| {
111
+ let kv = leaf_edge. next_kv ( ) ;
112
+ let kv = unsafe { unwrap_unchecked ( kv. ok ( ) ) } ;
113
+ ( kv. next_leaf_edge ( ) , kv. into_kv ( ) )
114
+ } )
107
115
}
108
116
109
117
/// Moves the leaf edge handle to the previous leaf edge and returns references to the
110
118
/// key and value in between.
111
119
/// Unsafe because the caller must ensure that the leaf edge is not the first one in the tree.
112
120
pub unsafe fn next_back_unchecked ( & mut self ) -> ( & ' a K , & ' a V ) {
113
- unsafe {
114
- replace ( self , |leaf_edge| {
115
- let kv = leaf_edge. next_back_kv ( ) ;
116
- let kv = unwrap_unchecked ( kv. ok ( ) ) ;
117
- ( kv. next_back_leaf_edge ( ) , kv. into_kv ( ) )
118
- } )
119
- }
121
+ replace ( self , |leaf_edge| {
122
+ let kv = leaf_edge. next_back_kv ( ) ;
123
+ let kv = unsafe { unwrap_unchecked ( kv. ok ( ) ) } ;
124
+ ( kv. next_back_leaf_edge ( ) , kv. into_kv ( ) )
125
+ } )
120
126
}
121
127
}
122
128
@@ -127,16 +133,14 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge
127
133
/// - The caller must ensure that the leaf edge is not the last one in the tree.
128
134
/// - Using the updated handle may well invalidate the returned references.
129
135
pub unsafe fn next_unchecked ( & mut self ) -> ( & ' a mut K , & ' a mut V ) {
130
- unsafe {
131
- let kv = replace ( self , |leaf_edge| {
132
- let kv = leaf_edge. next_kv ( ) ;
133
- let kv = unwrap_unchecked ( kv. ok ( ) ) ;
134
- ( ptr:: read ( & kv) . next_leaf_edge ( ) , kv)
135
- } ) ;
136
- // Doing the descend (and perhaps another move) invalidates the references
137
- // returned by `into_kv_mut`, so we have to do this last.
138
- kv. into_kv_mut ( )
139
- }
136
+ let kv = replace ( self , |leaf_edge| {
137
+ let kv = leaf_edge. next_kv ( ) ;
138
+ let kv = unsafe { unwrap_unchecked ( kv. ok ( ) ) } ;
139
+ ( unsafe { ptr:: read ( & kv) } . next_leaf_edge ( ) , kv)
140
+ } ) ;
141
+ // Doing the descend (and perhaps another move) invalidates the references
142
+ // returned by `into_kv_mut`, so we have to do this last.
143
+ kv. into_kv_mut ( )
140
144
}
141
145
142
146
/// Moves the leaf edge handle to the previous leaf and returns references to the
@@ -145,16 +149,14 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge
145
149
/// - The caller must ensure that the leaf edge is not the first one in the tree.
146
150
/// - Using the updated handle may well invalidate the returned references.
147
151
pub unsafe fn next_back_unchecked ( & mut self ) -> ( & ' a mut K , & ' a mut V ) {
148
- unsafe {
149
- let kv = replace ( self , |leaf_edge| {
150
- let kv = leaf_edge. next_back_kv ( ) ;
151
- let kv = unwrap_unchecked ( kv. ok ( ) ) ;
152
- ( ptr:: read ( & kv) . next_back_leaf_edge ( ) , kv)
153
- } ) ;
154
- // Doing the descend (and perhaps another move) invalidates the references
155
- // returned by `into_kv_mut`, so we have to do this last.
156
- kv. into_kv_mut ( )
157
- }
152
+ let kv = replace ( self , |leaf_edge| {
153
+ let kv = leaf_edge. next_back_kv ( ) ;
154
+ let kv = unsafe { unwrap_unchecked ( kv. ok ( ) ) } ;
155
+ ( unsafe { ptr:: read ( & kv) } . next_back_leaf_edge ( ) , kv)
156
+ } ) ;
157
+ // Doing the descend (and perhaps another move) invalidates the references
158
+ // returned by `into_kv_mut`, so we have to do this last.
159
+ kv. into_kv_mut ( )
158
160
}
159
161
}
160
162
@@ -172,14 +174,12 @@ impl<K, V> Handle<NodeRef<marker::Owned, K, V, marker::Leaf>, marker::Edge> {
172
174
/// call this method again subject to both preconditions listed in the first point,
173
175
/// or call counterpart `next_back_unchecked` subject to its preconditions.
174
176
pub unsafe fn next_unchecked ( & mut self ) -> ( K , V ) {
175
- unsafe {
176
- replace ( self , |leaf_edge| {
177
- let kv = next_kv_unchecked_dealloc ( leaf_edge) ;
178
- let k = ptr:: read ( kv. reborrow ( ) . into_kv ( ) . 0 ) ;
179
- let v = ptr:: read ( kv. reborrow ( ) . into_kv ( ) . 1 ) ;
180
- ( kv. next_leaf_edge ( ) , ( k, v) )
181
- } )
182
- }
177
+ replace ( self , |leaf_edge| {
178
+ let kv = unsafe { next_kv_unchecked_dealloc ( leaf_edge) } ;
179
+ let k = unsafe { ptr:: read ( kv. reborrow ( ) . into_kv ( ) . 0 ) } ;
180
+ let v = unsafe { ptr:: read ( kv. reborrow ( ) . into_kv ( ) . 1 ) } ;
181
+ ( kv. next_leaf_edge ( ) , ( k, v) )
182
+ } )
183
183
}
184
184
185
185
/// Moves the leaf edge handle to the previous leaf edge and returns the key
@@ -195,14 +195,12 @@ impl<K, V> Handle<NodeRef<marker::Owned, K, V, marker::Leaf>, marker::Edge> {
195
195
/// call this method again subject to both preconditions listed in the first point,
196
196
/// or call counterpart `next_unchecked` subject to its preconditions.
197
197
pub unsafe fn next_back_unchecked ( & mut self ) -> ( K , V ) {
198
- unsafe {
199
- replace ( self , |leaf_edge| {
200
- let kv = next_back_kv_unchecked_dealloc ( leaf_edge) ;
201
- let k = ptr:: read ( kv. reborrow ( ) . into_kv ( ) . 0 ) ;
202
- let v = ptr:: read ( kv. reborrow ( ) . into_kv ( ) . 1 ) ;
203
- ( kv. next_back_leaf_edge ( ) , ( k, v) )
204
- } )
205
- }
198
+ replace ( self , |leaf_edge| {
199
+ let kv = unsafe { next_back_kv_unchecked_dealloc ( leaf_edge) } ;
200
+ let k = unsafe { ptr:: read ( kv. reborrow ( ) . into_kv ( ) . 0 ) } ;
201
+ let v = unsafe { ptr:: read ( kv. reborrow ( ) . into_kv ( ) . 1 ) } ;
202
+ ( kv. next_back_leaf_edge ( ) , ( k, v) )
203
+ } )
206
204
}
207
205
}
208
206
0 commit comments