@@ -23,8 +23,8 @@ use num::{Int, UnsignedInt};
23
23
use ops:: { Deref , DerefMut , Drop } ;
24
24
use option:: Option ;
25
25
use 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 } ;
28
28
use collections:: hash_state:: HashState ;
29
29
30
30
const EMPTY_BUCKET : u64 = 0u64 ;
@@ -69,10 +69,11 @@ const EMPTY_BUCKET: u64 = 0u64;
69
69
pub struct RawTable < K , V > {
70
70
capacity : usize ,
71
71
size : usize ,
72
- hashes : * mut u64 ,
72
+ hashes : Unique < u64 > ,
73
+
73
74
// Because K/V do not appear directly in any of the types in the struct,
74
75
// 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 ) > ,
76
77
}
77
78
78
79
unsafe 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> {}
81
82
struct RawBucket < K , V > {
82
83
hash : * mut u64 ,
83
84
key : * mut K ,
84
- val : * mut V
85
+ val : * mut V ,
86
+ _marker : marker:: PhantomData < ( K , V ) > ,
85
87
}
86
88
87
89
impl < K , V > Copy for RawBucket < K , V > { }
@@ -170,11 +172,12 @@ fn can_alias_safehash_as_u64() {
170
172
}
171
173
172
174
impl < 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 > {
174
176
RawBucket {
175
177
hash : self . hash . offset ( count) ,
176
178
key : self . key . offset ( count) ,
177
179
val : self . val . offset ( count) ,
180
+ _marker : marker:: PhantomData ,
178
181
}
179
182
}
180
183
}
@@ -567,10 +570,11 @@ impl<K, V> RawTable<K, V> {
567
570
return RawTable {
568
571
size : 0 ,
569
572
capacity : 0 ,
570
- hashes : ptr :: null_mut ( ) ,
571
- marker : marker:: CovariantType ,
573
+ hashes : Unique :: new ( EMPTY as * mut u64 ) ,
574
+ marker : marker:: PhantomData ,
572
575
} ;
573
576
}
577
+
574
578
// No need for `checked_mul` before a more restrictive check performed
575
579
// later in this method.
576
580
let hashes_size = capacity * size_of :: < u64 > ( ) ;
@@ -606,25 +610,26 @@ impl<K, V> RawTable<K, V> {
606
610
RawTable {
607
611
capacity : capacity,
608
612
size : 0 ,
609
- hashes : hashes,
610
- marker : marker:: CovariantType ,
613
+ hashes : Unique :: new ( hashes) ,
614
+ marker : marker:: PhantomData ,
611
615
}
612
616
}
613
617
614
618
fn first_bucket_raw ( & self ) -> RawBucket < K , V > {
615
619
let hashes_size = self . capacity * size_of :: < u64 > ( ) ;
616
620
let keys_size = self . capacity * size_of :: < K > ( ) ;
617
621
618
- let buffer = self . hashes as * mut u8 ;
622
+ let buffer = * self . hashes as * mut u8 ;
619
623
let ( keys_offset, vals_offset) = calculate_offsets ( hashes_size,
620
624
keys_size, min_align_of :: < K > ( ) ,
621
625
min_align_of :: < V > ( ) ) ;
622
626
623
627
unsafe {
624
628
RawBucket {
625
- hash : self . hashes ,
629
+ hash : * self . hashes ,
626
630
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 ,
628
633
}
629
634
}
630
635
}
@@ -634,7 +639,7 @@ impl<K, V> RawTable<K, V> {
634
639
pub fn new ( capacity : usize ) -> RawTable < K , V > {
635
640
unsafe {
636
641
let ret = RawTable :: new_uninitialized ( capacity) ;
637
- zero_memory ( ret. hashes , capacity) ;
642
+ zero_memory ( * ret. hashes , capacity) ;
638
643
ret
639
644
}
640
645
}
@@ -656,7 +661,7 @@ impl<K, V> RawTable<K, V> {
656
661
hashes_end : unsafe {
657
662
self . hashes . offset ( self . capacity as isize )
658
663
} ,
659
- marker : marker:: ContravariantLifetime ,
664
+ marker : marker:: PhantomData ,
660
665
}
661
666
}
662
667
@@ -681,7 +686,7 @@ impl<K, V> RawTable<K, V> {
681
686
iter : RawBuckets {
682
687
raw : raw,
683
688
hashes_end : hashes_end,
684
- marker : marker:: ContravariantLifetime ,
689
+ marker : marker:: PhantomData ,
685
690
} ,
686
691
table : self ,
687
692
}
@@ -694,7 +699,7 @@ impl<K, V> RawTable<K, V> {
694
699
iter : RawBuckets {
695
700
raw : raw,
696
701
hashes_end : hashes_end,
697
- marker : marker:: ContravariantLifetime :: < ' static > ,
702
+ marker : marker:: PhantomData ,
698
703
} ,
699
704
table : self ,
700
705
}
@@ -708,7 +713,7 @@ impl<K, V> RawTable<K, V> {
708
713
raw : raw_bucket. offset ( self . capacity as isize ) ,
709
714
hashes_end : raw_bucket. hash ,
710
715
elems_left : self . size ,
711
- marker : marker:: ContravariantLifetime ,
716
+ marker : marker:: PhantomData ,
712
717
}
713
718
}
714
719
}
@@ -718,7 +723,13 @@ impl<K, V> RawTable<K, V> {
718
723
struct RawBuckets < ' a , K , V > {
719
724
raw : RawBucket < K , V > ,
720
725
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 ( ) > ,
722
733
}
723
734
724
735
// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
@@ -727,7 +738,7 @@ impl<'a, K, V> Clone for RawBuckets<'a, K, V> {
727
738
RawBuckets {
728
739
raw : self . raw ,
729
740
hashes_end : self . hashes_end ,
730
- marker : marker:: ContravariantLifetime ,
741
+ marker : marker:: PhantomData ,
731
742
}
732
743
}
733
744
}
@@ -759,7 +770,11 @@ struct RevMoveBuckets<'a, K, V> {
759
770
raw : RawBucket < K , V > ,
760
771
hashes_end : * mut u64 ,
761
772
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 ( ) > ,
763
778
}
764
779
765
780
impl < ' a , K , V > Iterator for RevMoveBuckets < ' a , K , V > {
@@ -966,9 +981,10 @@ impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
966
981
#[ unsafe_destructor]
967
982
impl < K , V > Drop for RawTable < K , V > {
968
983
fn drop ( & mut self ) {
969
- if self . hashes . is_null ( ) {
984
+ if self . capacity == 0 {
970
985
return ;
971
986
}
987
+
972
988
// This is done in reverse because we've likely partially taken
973
989
// some elements out with `.into_iter()` from the front.
974
990
// 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> {
986
1002
vals_size, min_align_of :: < V > ( ) ) ;
987
1003
988
1004
unsafe {
989
- deallocate ( self . hashes as * mut u8 , size, align) ;
1005
+ deallocate ( * self . hashes as * mut u8 , size, align) ;
990
1006
// Remember how everything was allocated out of one buffer
991
1007
// during initialization? We only need one call to free here.
992
1008
}
0 commit comments