Skip to content

Commit 92c2f4c

Browse files
committed
use BorrowFrom
1 parent fadb17a commit 92c2f4c

File tree

2 files changed

+66
-45
lines changed

2 files changed

+66
-45
lines changed

src/libstd/collections/hash/map.rs

+16-12
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
use self::Entry::*;
1414
use self::VacantEntryState::*;
1515

16-
use borrow::BorrowFrom;
16+
use borrow::{BorrowFrom, BorrowFromMut};
1717
use clone::Clone;
1818
use cmp::{max, Eq, PartialEq};
1919
use default::Default;
@@ -36,7 +36,8 @@ use super::table::{
3636
FullBucketImm,
3737
FullBucketMut,
3838
RawTable,
39-
SafeHash
39+
SafeHash,
40+
TableRef,
4041
};
4142
use super::table::BucketState::{
4243
Empty,
@@ -321,12 +322,13 @@ fn search_hashed<K, V, M, F>(table: M,
321322
hash: SafeHash,
322323
mut is_match: F)
323324
-> InternalEntry<K, V, M> where
324-
M: Deref<Target=RawTable<K, V>>,
325+
RawTable<K, V>: BorrowFrom<M>,
325326
F: FnMut(&K) -> bool,
326327
{
327328
// Worst case, we'll find one empty bucket among `size + 1` buckets.
329+
let table = TableRef(table);
328330
let size = table.size();
329-
let mut probe = match Bucket::new(table, hash) {
331+
let mut probe = match Bucket::new(table.0, hash) {
330332
Some(probe) => probe,
331333
None => return InternalEntry::TableIsEmpty,
332334
};
@@ -418,7 +420,8 @@ fn robin_hood<'a, K: 'a, V: 'a>(mut bucket: FullBucketMut<'a, K, V>,
418420
let b = bucket.put(old_hash, old_key, old_val);
419421
// Now that it's stolen, just read the value's pointer
420422
// right out of the table!
421-
let starting_bucket = Bucket::at_index(b.into_table(), starting_index).unwrap()
423+
let starting_bucket = Bucket::at_index(b.into_table(), starting_index).ok()
424+
.unwrap()
422425
.peek();
423426
if let Full(starting_bucket) = starting_bucket {
424427
return starting_bucket.into_mut_refs().1;
@@ -448,10 +451,11 @@ fn robin_hood<'a, K: 'a, V: 'a>(mut bucket: FullBucketMut<'a, K, V>,
448451
// Performs insertion with relaxed requirements.
449452
// The caller should ensure that invariants of Robin Hood linear probing hold.
450453
fn insert_hashed_ordered<M, K, V>(arg: M, h: SafeHash, k: K, v: V) -> M
451-
where M: Deref<Target=RawTable<K, V>> + DerefMut
454+
where RawTable<K, V>: BorrowFromMut<M>
452455
{
453-
let cap = arg.capacity();
454-
let mut buckets = Bucket::new(arg, h).unwrap();
456+
let table = TableRef(arg);
457+
let cap = table.capacity();
458+
let mut buckets = Bucket::new(table.0, h).unwrap();
455459
let ib = buckets.index();
456460

457461
while buckets.index() != ib + cap {
@@ -670,7 +674,7 @@ impl<K, V, S, H> HashMap<K, V, S>
670674
// Iterate over `old_capacity` buckets, which constitute half of
671675
// the table which was resized in-place, or the entire
672676
// `old_table`.
673-
let mut bucket = Bucket::at_index(&mut self.table, 0).unwrap().iter_to(old_capacity);
677+
let mut bucket = Bucket::at_index(&mut self.table, 0).ok().unwrap().iter_to(old_capacity);
674678

675679
// "So a few of the first shall be last: for many be called,
676680
// but few chosen."
@@ -1004,7 +1008,7 @@ impl<K, V, S, H> HashMap<K, V, S>
10041008
reason = "matches collection reform specification, waiting for dust to settle")]
10051009
pub fn drain(&mut self) -> Drain<K, V> {
10061010
Drain {
1007-
inner: Bucket::at_index(&mut self.table, 0)
1011+
inner: Bucket::at_index(&mut self.table, 0).ok()
10081012
}
10091013
}
10101014

@@ -1516,7 +1520,7 @@ impl<'a, K, V> Entry<'a, K, V> {
15161520

15171521
#[unstable(feature = "std_misc",
15181522
reason = "matches collection reform v2 specification, waiting for dust to settle")]
1519-
impl<K, V, M: Deref<Target=RawTable<K, V>>> OccupiedEntryState<K, V, M> {
1523+
impl<K, V, M> OccupiedEntryState<K, V, M> where RawTable<K, V>: BorrowFrom<M> {
15201524
/// Gets a reference to the value in the entry.
15211525
pub fn get(&self) -> &V {
15221526
self.elem.read().2
@@ -1525,7 +1529,7 @@ impl<K, V, M: Deref<Target=RawTable<K, V>>> OccupiedEntryState<K, V, M> {
15251529

15261530
#[unstable(feature = "std_misc",
15271531
reason = "matches collection reform v2 specification, waiting for dust to settle")]
1528-
impl<K, V, M: DerefMut<Target=RawTable<K, V>>> OccupiedEntryState<K, V, M> {
1532+
impl<K, V, M> OccupiedEntryState<K, V, M> where RawTable<K, V>: BorrowFromMut<M> {
15291533
/// Gets a mutable reference to the value in the entry.
15301534
pub fn get_mut(&mut self) -> &mut V {
15311535
self.elem.read_mut().2

src/libstd/collections/hash/table.rs

+50-33
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
use self::BucketState::*;
1414

15+
use borrow::{BorrowFrom, BorrowFromMut};
1516
use clone::Clone;
1617
use cmp;
1718
use hash::{Hash, Hasher};
@@ -78,11 +79,16 @@ struct RawBucket<K, V, M> {
7879

7980
impl<K,V,M> Copy for RawBucket<K,V,M> {}
8081

82+
#[derive(Clone)]
83+
pub struct TableRef<M>(M);
84+
85+
impl<M: Copy> Copy for TableRef<M> {}
86+
8187
struct BareBucket<K, V, M> {
8288
raw: RawBucket<K, V, M>,
8389
idx: usize,
8490
capacity: usize,
85-
table: M,
91+
table: TableRef<M>,
8692
}
8793

8894
impl<K,V,M:Copy> Copy for BareBucket<K,V,M> {}
@@ -151,11 +157,19 @@ fn can_alias_safehash_as_option() {
151157
assert_eq!(size_of::<SafeHash>(), size_of::<Option<SafeHash>>())
152158
}
153159

154-
impl<K, V> Deref for RawTable<K, V> {
160+
#[old_impl_check]
161+
impl<K, V, M> Deref for TableRef<M> where RawTable<K, V>: BorrowFrom<M> {
155162
type Target = RawTable<K, V>;
156163

157164
fn deref(&self) -> &RawTable<K, V> {
158-
self
165+
BorrowFrom::borrow_from(&mut self.0)
166+
}
167+
}
168+
169+
#[old_impl_check]
170+
impl<K, V, M> DerefMut for TableRef<M> where RawTable<K, V>: BorrowFromMut<M> {
171+
fn deref_mut(&mut self) -> &mut RawTable<K, V> {
172+
BorrowFromMut::borrow_from_mut(&mut self.0)
159173
}
160174
}
161175

@@ -168,7 +182,7 @@ impl<K, V, M> RawBucket<K, V, M> {
168182
}
169183
}
170184

171-
impl<'t, K, V, M: Deref<Target=RawTable<K, V>> + 't> RawBucket<K, V, M> {
185+
impl<'t, K, V, M: 't> RawBucket<K, V, M> where RawTable<K, V>: BorrowFrom<M> {
172186
pub fn into_refs(self) -> (&'t K, &'t V) {
173187
let &(ref k, ref v) = unsafe {
174188
&*self.kval
@@ -178,7 +192,7 @@ impl<'t, K, V, M: Deref<Target=RawTable<K, V>> + 't> RawBucket<K, V, M> {
178192
}
179193

180194
impl<'t, K, V, M> RawBucket<K, V, M>
181-
where M: Deref<Target=RawTable<K, V>> + DerefMut + 't
195+
where RawTable<K, V>: BorrowFromMut<M>, M: 't
182196
{
183197
pub fn into_mut_refs(self) -> (&'t mut K, &'t mut V) {
184198
let &mut (ref mut k, ref mut v) = unsafe {
@@ -190,29 +204,31 @@ impl<'t, K, V, M> RawBucket<K, V, M>
190204

191205
// Chain buckets! This is perfectly safe as long as operations on one
192206
// `Bucket` can't invalidate other `Bucket`s.
193-
impl<K, V, M: Deref<Target=RawTable<K, V>>> Deref for Bucket<K, V, M> {
194-
type Target = RawTable<K, V>;
195-
196-
fn deref(&self) -> &RawTable<K, V> {
197-
&*self.0.table
207+
impl<K, V, M> BorrowFrom<Bucket<K, V, M>> for RawTable<K, V>
208+
where RawTable<K, V>: BorrowFrom<M>
209+
{
210+
fn borrow_from(bucket: &Bucket<K, V, M>) -> &RawTable<K, V> {
211+
BorrowFrom::borrow_from(&bucket.0.table.0)
198212
}
199213
}
200214

201-
impl<K, V, M: DerefMut<Target=RawTable<K, V>>> DerefMut for Bucket<K, V, M> {
202-
fn deref_mut(&mut self) -> &mut RawTable<K, V> {
203-
&mut *self.0.table
215+
impl<K, V, M> BorrowFromMut<Bucket<K, V, M>> for RawTable<K, V>
216+
where RawTable<K, V>: BorrowFromMut<M>
217+
{
218+
fn borrow_from_mut(bucket: &mut Bucket<K, V, M>) -> &mut RawTable<K, V> {
219+
BorrowFromMut::borrow_from_mut(&mut bucket.0.table.0)
204220
}
205221
}
206222

207223
// Buckets hold references to the table.
208224
impl<K, V, M, S> Bucket<K, V, M, S> {
209225
/// Borrow a reference to the table.
210226
pub fn table(&self) -> &M {
211-
&self.0.table
227+
&self.0.table.0
212228
}
213229
/// Move out the reference to the table.
214230
pub fn into_table(self) -> M {
215-
self.0.table
231+
self.0.table.0
216232
}
217233
/// Get the raw index.
218234
pub fn index(&self) -> uint {
@@ -221,23 +237,24 @@ impl<K, V, M, S> Bucket<K, V, M, S> {
221237
/// Turn the bucket into an iterator over full buckets.
222238
pub fn into_iter(self) -> RawFullBuckets<K, V, M> {
223239
RawFullBuckets {
224-
raw: self.raw,
240+
raw: self.0.raw,
225241
hashes_end: unsafe {
226-
self.raw.hash.offset(self.0.capacity as int - self.index() as int)
242+
self.0.raw.hash.offset(self.0.capacity as int - self.index() as int)
227243
},
228-
table: self.table,
244+
table: self.0.table,
229245
}
230246
}
231247
}
232248

233-
impl<K, V, M: Deref<Target=RawTable<K, V>>> Bucket<K, V, M> {
249+
impl<K, V, M> Bucket<K, V, M> where RawTable<K, V>: BorrowFrom<M> {
234250
pub fn new(table: M, hash: SafeHash) -> Option<Bucket<K, V, M>> {
235251
Bucket::at_index(table, *hash as usize).ok()
236252
}
237253

238254
pub fn at_index(table: M, ib_index: uint)
239255
-> Result<Bucket<K, V, M>, Bucket<K, V, M, bucket::TableIsEmpty>>
240256
{
257+
let table = TableRef(table);
241258
let ib_index = ib_index & (table.capacity() - 1);
242259
let bb = BareBucket {
243260
raw: unsafe {
@@ -261,7 +278,7 @@ impl<K, V, M: Deref<Target=RawTable<K, V>>> Bucket<K, V, M> {
261278

262279
/// Narrows down the range of iteration, which must be a power of 2.
263280
pub fn iter_to(mut self, limit: usize) -> Bucket<K, V, M> {
264-
assert!(limit <= self.capacity);
281+
assert!(limit <= TableRef(&self.table).capacity());
265282
assert!(limit.is_power_of_two());
266283
self.0.capacity = limit;
267284
self
@@ -294,7 +311,7 @@ impl<K, V, M: Deref<Target=RawTable<K, V>>> Bucket<K, V, M> {
294311
}
295312
}
296313

297-
impl<K, V, M: Deref<Target=RawTable<K, V>> + DerefMut> Bucket<K, V, M> {
314+
impl<K, V, M> Bucket<K, V, M> where RawTable<K, V>: BorrowFromMut<M> {
298315
/// A combination of `peek` and `take` which doesn't consume the bucket.
299316
pub fn peek_take(&mut self) -> Option<(K, V)> {
300317
unsafe {
@@ -310,7 +327,7 @@ impl<K, V, M: Deref<Target=RawTable<K, V>> + DerefMut> Bucket<K, V, M> {
310327
}
311328
}
312329

313-
impl<K, V, M: Deref<Target=RawTable<K, V>>, S> Bucket<K, V, M, S> {
330+
impl<K, V, M, S> Bucket<K, V, M, S> where RawTable<K, V>: BorrowFrom<M> {
314331
#[inline]
315332
pub fn into_next(self) -> Bucket<K, V, M> {
316333
let mut bucket = self.into_bucket();
@@ -324,10 +341,10 @@ impl<K, V, M: Deref<Target=RawTable<K, V>>, S> Bucket<K, V, M, S> {
324341
}
325342
}
326343

327-
impl<K, V, M: Deref<Target=RawTable<K, V>>> EmptyBucket<K, V, M> {
344+
impl<K, V, M> EmptyBucket<K, V, M> where RawTable<K, V>: BorrowFrom<M> {
328345
pub fn gap_peek(self) -> Option<GapThenFull<K, V, M>> {
329346
let gap = Bucket(BareBucket {
330-
table: (),
347+
table: TableRef(()),
331348
idx: self.0.idx,
332349
capacity: self.0.capacity,
333350
raw: RawBucket {
@@ -348,7 +365,7 @@ impl<K, V, M: Deref<Target=RawTable<K, V>>> EmptyBucket<K, V, M> {
348365
}
349366
}
350367

351-
impl<K, V, M: Deref<Target=RawTable<K, V>> + DerefMut> EmptyBucket<K, V, M> {
368+
impl<K, V, M> EmptyBucket<K, V, M> where RawTable<K, V>: BorrowFromMut<M> {
352369
/// Puts given key and value pair, along with the key's hash,
353370
/// into this bucket in the hashtable. Note how `self` is 'moved' into
354371
/// this function, because this slot will no longer be empty when
@@ -369,7 +386,7 @@ impl<K, V, M: Deref<Target=RawTable<K, V>> + DerefMut> EmptyBucket<K, V, M> {
369386
}
370387
}
371388

372-
impl<K, V, M: Deref<Target=RawTable<K, V>>> FullBucket<K, V, M> {
389+
impl<K, V, M> FullBucket<K, V, M> where RawTable<K, V>: BorrowFrom<M> {
373390
/// Get the distance between this bucket and the 'ideal' location
374391
/// as determined by the key's hash stored in it.
375392
///
@@ -391,7 +408,7 @@ impl<K, V, M: Deref<Target=RawTable<K, V>>> FullBucket<K, V, M> {
391408
}
392409
}
393410

394-
impl<K, V, M: Deref<Target=RawTable<K, V>> + DerefMut> FullBucket<K, V, M> {
411+
impl<K, V, M> FullBucket<K, V, M> where RawTable<K, V>: BorrowFromMut<M> {
395412
/// Removes this bucket's key and value from the hashtable.
396413
///
397414
/// This works similarly to `put`, building an `EmptyBucket` out of the
@@ -415,7 +432,7 @@ impl<K, V, M: Deref<Target=RawTable<K, V>> + DerefMut> FullBucket<K, V, M> {
415432
}
416433
}
417434

418-
impl<'t, K, V, M: Deref<Target=RawTable<K, V>> + 't> FullBucket<K, V, M> {
435+
impl<'t, K, V, M: 't> FullBucket<K, V, M> where RawTable<K, V>: BorrowFrom<M> {
419436
/// Exchange a bucket state for immutable references into the table.
420437
/// Because the underlying reference to the table is also consumed,
421438
/// no further changes to the structure of the table are possible;
@@ -426,15 +443,15 @@ impl<'t, K, V, M: Deref<Target=RawTable<K, V>> + 't> FullBucket<K, V, M> {
426443
}
427444
}
428445

429-
impl<'t, K, V, M: Deref<Target=RawTable<K, V>> + DerefMut + 't> FullBucket<K, V, M> {
446+
impl<'t, K, V, M: 't> FullBucket<K, V, M> where RawTable<K, V>: BorrowFromMut<M> {
430447
/// This works similarly to `into_refs`, exchanging a bucket state
431448
/// for mutable references into the table.
432449
pub fn into_mut_refs(self) -> (&'t mut K, &'t mut V) {
433450
self.0.raw.into_mut_refs()
434451
}
435452
}
436453

437-
impl<K, V, M: Deref<Target=RawTable<K, V>>> GapThenFull<K, V, M> {
454+
impl<K, V, M> GapThenFull<K, V, M> where RawTable<K, V>: BorrowFrom<M> {
438455
#[inline]
439456
pub fn full(&self) -> &FullBucket<K, V, M> {
440457
&self.full
@@ -636,7 +653,7 @@ impl<K, V, M> DerefMut for RawFullBucket<K, V, M> {
636653
pub struct RawFullBuckets<K, V, M> {
637654
raw: RawBucket<K, V, M>,
638655
hashes_end: *mut Option<SafeHash>,
639-
table: M,
656+
table: TableRef<M>,
640657
}
641658

642659
// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
@@ -710,12 +727,12 @@ impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
710727

711728
{
712729
let cap = self.capacity();
713-
let mut buckets = if let Some(buckets) = Bucket::at_index(self, 0) {
730+
let mut buckets = if let Ok(buckets) = Bucket::at_index(self, 0) {
714731
buckets
715732
} else {
716733
return new_ht;
717734
};
718-
let mut new_buckets = Bucket::at_index(&mut new_ht, 0).unwrap();
735+
let mut new_buckets = Bucket::at_index(&mut new_ht, 0).ok().unwrap();
719736
while buckets.index() != cap {
720737
match buckets.peek() {
721738
Full(full) => {

0 commit comments

Comments
 (0)