@@ -23,8 +23,8 @@ use num::{Int, UnsignedInt};
2323use ops:: { Deref , DerefMut , Drop } ;
2424use option:: Option ;
2525use option:: Option :: { Some , None } ;
26- use ptr:: { self , PtrExt , copy_nonoverlapping_memory, zero_memory} ;
27- use rt:: heap:: { allocate, deallocate} ;
26+ use ptr:: { self , PtrExt , copy_nonoverlapping_memory, Unique , zero_memory} ;
27+ use rt:: heap:: { allocate, deallocate, EMPTY } ;
2828use collections:: hash_state:: HashState ;
2929
3030const EMPTY_BUCKET : u64 = 0u64 ;
@@ -69,10 +69,11 @@ const EMPTY_BUCKET: u64 = 0u64;
6969pub struct RawTable < K , V > {
7070 capacity : usize ,
7171 size : usize ,
72- hashes : * mut u64 ,
72+ hashes : Unique < u64 > ,
73+
7374 // Because K/V do not appear directly in any of the types in the struct,
7475 // inform rustc that in fact instances of K and V are reachable from here.
75- marker : marker:: CovariantType < ( K , V ) > ,
76+ marker : marker:: PhantomData < ( K , V ) > ,
7677}
7778
7879unsafe impl < K : Send , V : Send > Send for RawTable < K , V > { }
@@ -81,7 +82,8 @@ unsafe impl<K: Sync, V: Sync> Sync for RawTable<K, V> {}
8182struct RawBucket < K , V > {
8283 hash : * mut u64 ,
8384 key : * mut K ,
84- val : * mut V
85+ val : * mut V ,
86+ _marker : marker:: PhantomData < ( K , V ) > ,
8587}
8688
8789impl < K , V > Copy for RawBucket < K , V > { }
@@ -170,11 +172,12 @@ fn can_alias_safehash_as_u64() {
170172}
171173
172174impl < K , V > RawBucket < K , V > {
173- unsafe fn offset ( self , count : int ) -> RawBucket < K , V > {
175+ unsafe fn offset ( self , count : isize ) -> RawBucket < K , V > {
174176 RawBucket {
175177 hash : self . hash . offset ( count) ,
176178 key : self . key . offset ( count) ,
177179 val : self . val . offset ( count) ,
180+ _marker : marker:: PhantomData ,
178181 }
179182 }
180183}
@@ -567,10 +570,11 @@ impl<K, V> RawTable<K, V> {
567570 return RawTable {
568571 size : 0 ,
569572 capacity : 0 ,
570- hashes : ptr :: null_mut ( ) ,
571- marker : marker:: CovariantType ,
573+ hashes : Unique :: new ( EMPTY as * mut u64 ) ,
574+ marker : marker:: PhantomData ,
572575 } ;
573576 }
577+
574578 // No need for `checked_mul` before a more restrictive check performed
575579 // later in this method.
576580 let hashes_size = capacity * size_of :: < u64 > ( ) ;
@@ -606,25 +610,26 @@ impl<K, V> RawTable<K, V> {
606610 RawTable {
607611 capacity : capacity,
608612 size : 0 ,
609- hashes : hashes,
610- marker : marker:: CovariantType ,
613+ hashes : Unique :: new ( hashes) ,
614+ marker : marker:: PhantomData ,
611615 }
612616 }
613617
614618 fn first_bucket_raw ( & self ) -> RawBucket < K , V > {
615619 let hashes_size = self . capacity * size_of :: < u64 > ( ) ;
616620 let keys_size = self . capacity * size_of :: < K > ( ) ;
617621
618- let buffer = self . hashes as * mut u8 ;
622+ let buffer = * self . hashes as * mut u8 ;
619623 let ( keys_offset, vals_offset) = calculate_offsets ( hashes_size,
620624 keys_size, min_align_of :: < K > ( ) ,
621625 min_align_of :: < V > ( ) ) ;
622626
623627 unsafe {
624628 RawBucket {
625- hash : self . hashes ,
629+ hash : * self . hashes ,
626630 key : buffer. offset ( keys_offset as isize ) as * mut K ,
627- val : buffer. offset ( vals_offset as isize ) as * mut V
631+ val : buffer. offset ( vals_offset as isize ) as * mut V ,
632+ _marker : marker:: PhantomData ,
628633 }
629634 }
630635 }
@@ -634,7 +639,7 @@ impl<K, V> RawTable<K, V> {
634639 pub fn new ( capacity : usize ) -> RawTable < K , V > {
635640 unsafe {
636641 let ret = RawTable :: new_uninitialized ( capacity) ;
637- zero_memory ( ret. hashes , capacity) ;
642+ zero_memory ( * ret. hashes , capacity) ;
638643 ret
639644 }
640645 }
@@ -656,7 +661,7 @@ impl<K, V> RawTable<K, V> {
656661 hashes_end : unsafe {
657662 self . hashes . offset ( self . capacity as isize )
658663 } ,
659- marker : marker:: ContravariantLifetime ,
664+ marker : marker:: PhantomData ,
660665 }
661666 }
662667
@@ -681,7 +686,7 @@ impl<K, V> RawTable<K, V> {
681686 iter : RawBuckets {
682687 raw : raw,
683688 hashes_end : hashes_end,
684- marker : marker:: ContravariantLifetime ,
689+ marker : marker:: PhantomData ,
685690 } ,
686691 table : self ,
687692 }
@@ -694,7 +699,7 @@ impl<K, V> RawTable<K, V> {
694699 iter : RawBuckets {
695700 raw : raw,
696701 hashes_end : hashes_end,
697- marker : marker:: ContravariantLifetime :: < ' static > ,
702+ marker : marker:: PhantomData ,
698703 } ,
699704 table : self ,
700705 }
@@ -708,7 +713,7 @@ impl<K, V> RawTable<K, V> {
708713 raw : raw_bucket. offset ( self . capacity as isize ) ,
709714 hashes_end : raw_bucket. hash ,
710715 elems_left : self . size ,
711- marker : marker:: ContravariantLifetime ,
716+ marker : marker:: PhantomData ,
712717 }
713718 }
714719}
@@ -718,7 +723,13 @@ impl<K, V> RawTable<K, V> {
718723struct RawBuckets < ' a , K , V > {
719724 raw : RawBucket < K , V > ,
720725 hashes_end : * mut u64 ,
721- marker : marker:: ContravariantLifetime < ' a > ,
726+
727+ // Strictly speaking, this should be &'a (K,V), but that would
728+ // require that K:'a, and we often use RawBuckets<'static...> for
729+ // move iterations, so that messes up a lot of other things. So
730+ // just use `&'a (K,V)` as this is not a publicly exposed type
731+ // anyway.
732+ marker : marker:: PhantomData < & ' a ( ) > ,
722733}
723734
724735// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
@@ -727,7 +738,7 @@ impl<'a, K, V> Clone for RawBuckets<'a, K, V> {
727738 RawBuckets {
728739 raw : self . raw ,
729740 hashes_end : self . hashes_end ,
730- marker : marker:: ContravariantLifetime ,
741+ marker : marker:: PhantomData ,
731742 }
732743 }
733744}
@@ -759,7 +770,11 @@ struct RevMoveBuckets<'a, K, V> {
759770 raw : RawBucket < K , V > ,
760771 hashes_end : * mut u64 ,
761772 elems_left : usize ,
762- marker : marker:: ContravariantLifetime < ' a > ,
773+
774+ // As above, `&'a (K,V)` would seem better, but we often use
775+ // 'static for the lifetime, and this is not a publicly exposed
776+ // type.
777+ marker : marker:: PhantomData < & ' a ( ) > ,
763778}
764779
765780impl < ' a , K , V > Iterator for RevMoveBuckets < ' a , K , V > {
@@ -966,9 +981,10 @@ impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
966981#[ unsafe_destructor]
967982impl < K , V > Drop for RawTable < K , V > {
968983 fn drop ( & mut self ) {
969- if self . hashes . is_null ( ) {
984+ if self . capacity == 0 {
970985 return ;
971986 }
987+
972988 // This is done in reverse because we've likely partially taken
973989 // some elements out with `.into_iter()` from the front.
974990 // Check if the size is 0, so we don't do a useless scan when
@@ -986,7 +1002,7 @@ impl<K, V> Drop for RawTable<K, V> {
9861002 vals_size, min_align_of :: < V > ( ) ) ;
9871003
9881004 unsafe {
989- deallocate ( self . hashes as * mut u8 , size, align) ;
1005+ deallocate ( * self . hashes as * mut u8 , size, align) ;
9901006 // Remember how everything was allocated out of one buffer
9911007 // during initialization? We only need one call to free here.
9921008 }
0 commit comments