1+ use core:: intrinsics;
2+ use core:: mem;
13use core:: ptr;
24
35use super :: node:: { marker, ForceResult :: * , Handle , NodeRef } ;
@@ -79,16 +81,24 @@ def_next_kv_uncheched_dealloc! {unsafe fn next_kv_unchecked_dealloc: right_kv}
7981def_next_kv_uncheched_dealloc ! { unsafe fn next_back_kv_unchecked_dealloc: left_kv}
8082
8183/// 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 .
8385///
84- /// Safety: The change closure must not panic .
86+ /// If a panic occurs in the ` change` closure, the entire process will be aborted .
8587#[ 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 ;
8796 let value = unsafe { ptr:: read ( v) } ;
8897 let ( new_value, ret) = change ( value) ;
8998 unsafe {
9099 ptr:: write ( v, new_value) ;
91100 }
101+ mem:: forget ( guard) ;
92102 ret
93103}
94104
@@ -97,26 +107,22 @@ impl<'a, K, V> Handle<NodeRef<marker::Immut<'a>, K, V, marker::Leaf>, marker::Ed
97107 /// key and value in between.
98108 /// Unsafe because the caller must ensure that the leaf edge is not the last one in the tree.
99109 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+ } )
107115 }
108116
109117 /// Moves the leaf edge handle to the previous leaf edge and returns references to the
110118 /// key and value in between.
111119 /// Unsafe because the caller must ensure that the leaf edge is not the first one in the tree.
112120 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+ } )
120126 }
121127}
122128
@@ -127,16 +133,14 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge
127133 /// - The caller must ensure that the leaf edge is not the last one in the tree.
128134 /// - Using the updated handle may well invalidate the returned references.
129135 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 ( )
140144 }
141145
142146 /// 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
145149 /// - The caller must ensure that the leaf edge is not the first one in the tree.
146150 /// - Using the updated handle may well invalidate the returned references.
147151 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 ( )
158160 }
159161}
160162
@@ -172,14 +174,12 @@ impl<K, V> Handle<NodeRef<marker::Owned, K, V, marker::Leaf>, marker::Edge> {
172174 /// call this method again subject to both preconditions listed in the first point,
173175 /// or call counterpart `next_back_unchecked` subject to its preconditions.
174176 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+ } )
183183 }
184184
185185 /// 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> {
195195 /// call this method again subject to both preconditions listed in the first point,
196196 /// or call counterpart `next_unchecked` subject to its preconditions.
197197 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+ } )
206204 }
207205}
208206
0 commit comments