@@ -83,16 +83,19 @@ impl<K, V> IndexMapCore<K, V> {
83
83
let entries = & * self . entries ;
84
84
let eq = move |& i: & usize | is_match ( & entries[ i] . key ) ;
85
85
match self . indices . find ( hash. get ( ) , eq) {
86
- // SAFETY: The entry is created with a live raw bucket, at the same time
87
- // we have a &mut reference to the map, so it can not be modified further.
88
- Some ( raw_bucket) => Ok ( RawTableEntry {
89
- map : self ,
90
- raw_bucket,
91
- } ) ,
86
+ // SAFETY: The bucket is valid because we *just* found it in this map.
87
+ Some ( raw_bucket) => Ok ( unsafe { RawTableEntry :: new ( self , raw_bucket) } ) ,
92
88
None => Err ( self ) ,
93
89
}
94
90
}
95
91
92
+ pub ( super ) fn index_raw_entry ( & mut self , index : usize ) -> Option < RawTableEntry < ' _ , K , V > > {
93
+ let hash = self . entries . get ( index) ?. hash ;
94
+ let raw_bucket = self . indices . find ( hash. get ( ) , move |& i| i == index) ?;
95
+ // SAFETY: The bucket is valid because we *just* found it in this map.
96
+ Some ( unsafe { RawTableEntry :: new ( self , raw_bucket) } )
97
+ }
98
+
96
99
pub ( super ) fn indices_mut ( & mut self ) -> impl Iterator < Item = & mut usize > {
97
100
// SAFETY: we're not letting any of the buckets escape this function,
98
101
// only the item references that are appropriately bound to `&mut self`.
@@ -113,6 +116,13 @@ pub(super) struct RawTableEntry<'a, K, V> {
113
116
unsafe impl < K : Sync , V : Sync > Sync for RawTableEntry < ' _ , K , V > { }
114
117
115
118
impl < ' a , K , V > RawTableEntry < ' a , K , V > {
119
+ /// The caller must ensure that the `raw_bucket` is valid in the given `map`,
120
+ /// and then we hold the `&mut` reference for exclusive access.
121
+ #[ inline]
122
+ unsafe fn new ( map : & ' a mut IndexMapCore < K , V > , raw_bucket : RawBucket ) -> Self {
123
+ Self { map, raw_bucket }
124
+ }
125
+
116
126
/// Return the index of the key-value pair
117
127
#[ inline]
118
128
pub ( super ) fn index ( & self ) -> usize {
@@ -146,6 +156,7 @@ impl<'a, K, V> RawTableEntry<'a, K, V> {
146
156
}
147
157
148
158
/// Take no action, just return the index and the original map reference.
159
+ #[ inline]
149
160
pub ( super ) fn into_inner ( self ) -> ( & ' a mut IndexMapCore < K , V > , usize ) {
150
161
let index = self . index ( ) ;
151
162
( self . map , index)
0 commit comments