|
86 | 86 | #![stable(feature = "rust1", since = "1.0.0")] |
87 | 87 |
|
88 | 88 | use crate::fmt; |
89 | | -use crate::marker; |
| 89 | +use crate::intrinsics::const_eval_select; |
| 90 | +use crate::marker::{self, Destruct}; |
90 | 91 |
|
91 | 92 | #[stable(feature = "rust1", since = "1.0.0")] |
92 | 93 | #[allow(deprecated)] |
@@ -183,6 +184,7 @@ mod sip; |
183 | 184 | /// [impl]: ../../std/primitive.str.html#impl-Hash-for-str |
184 | 185 | #[stable(feature = "rust1", since = "1.0.0")] |
185 | 186 | #[rustc_diagnostic_item = "Hash"] |
| 187 | +#[const_trait] |
186 | 188 | pub trait Hash { |
187 | 189 | /// Feeds this value into the given [`Hasher`]. |
188 | 190 | /// |
@@ -234,13 +236,25 @@ pub trait Hash { |
234 | 236 | /// [`hash`]: Hash::hash |
235 | 237 | /// [`hash_slice`]: Hash::hash_slice |
236 | 238 | #[stable(feature = "hash_slice", since = "1.3.0")] |
237 | | - fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) |
| 239 | + fn hash_slice<H: ~const Hasher>(data: &[Self], state: &mut H) |
238 | 240 | where |
239 | 241 | Self: Sized, |
240 | 242 | { |
241 | | - for piece in data { |
242 | | - piece.hash(state); |
| 243 | + //FIXME(const_trait_impl): revert to only a for loop |
| 244 | + fn rt<T: Hash, H: Hasher>(data: &[T], state: &mut H) { |
| 245 | + for piece in data { |
| 246 | + piece.hash(state) |
| 247 | + } |
| 248 | + } |
| 249 | + const fn ct<T: ~const Hash, H: ~const Hasher>(data: &[T], state: &mut H) { |
| 250 | + let mut i = 0; |
| 251 | + while i < data.len() { |
| 252 | + data[i].hash(state); |
| 253 | + i += 1; |
| 254 | + } |
243 | 255 | } |
| 256 | + // SAFETY: same behavior, CT just uses while instead of for |
| 257 | + unsafe { const_eval_select((data, state), ct, rt) }; |
244 | 258 | } |
245 | 259 | } |
246 | 260 |
|
@@ -313,6 +327,7 @@ pub use macros::Hash; |
313 | 327 | /// [`write_u8`]: Hasher::write_u8 |
314 | 328 | /// [`write_u32`]: Hasher::write_u32 |
315 | 329 | #[stable(feature = "rust1", since = "1.0.0")] |
| 330 | +#[const_trait] |
316 | 331 | pub trait Hasher { |
317 | 332 | /// Returns the hash value for the values written so far. |
318 | 333 | /// |
@@ -558,7 +573,8 @@ pub trait Hasher { |
558 | 573 | } |
559 | 574 |
|
560 | 575 | #[stable(feature = "indirect_hasher_impl", since = "1.22.0")] |
561 | | -impl<H: Hasher + ?Sized> Hasher for &mut H { |
| 576 | +#[rustc_const_unstable(feature = "const_hash", issue = "104061")] |
| 577 | +impl<H: ~const Hasher + ?Sized> const Hasher for &mut H { |
562 | 578 | fn finish(&self) -> u64 { |
563 | 579 | (**self).finish() |
564 | 580 | } |
@@ -638,6 +654,7 @@ impl<H: Hasher + ?Sized> Hasher for &mut H { |
638 | 654 | /// [`build_hasher`]: BuildHasher::build_hasher |
639 | 655 | /// [`HashMap`]: ../../std/collections/struct.HashMap.html |
640 | 656 | #[stable(since = "1.7.0", feature = "build_hasher")] |
| 657 | +#[const_trait] |
641 | 658 | pub trait BuildHasher { |
642 | 659 | /// Type of the hasher that will be created. |
643 | 660 | #[stable(since = "1.7.0", feature = "build_hasher")] |
@@ -698,9 +715,10 @@ pub trait BuildHasher { |
698 | 715 | /// ); |
699 | 716 | /// ``` |
700 | 717 | #[unstable(feature = "build_hasher_simple_hash_one", issue = "86161")] |
701 | | - fn hash_one<T: Hash>(&self, x: T) -> u64 |
| 718 | + fn hash_one<T: ~const Hash + ~const Destruct>(&self, x: T) -> u64 |
702 | 719 | where |
703 | 720 | Self: Sized, |
| 721 | + Self::Hasher: ~const Hasher + ~const Destruct, |
704 | 722 | { |
705 | 723 | let mut hasher = self.build_hasher(); |
706 | 724 | x.hash(&mut hasher); |
@@ -764,7 +782,8 @@ impl<H> fmt::Debug for BuildHasherDefault<H> { |
764 | 782 | } |
765 | 783 |
|
766 | 784 | #[stable(since = "1.7.0", feature = "build_hasher")] |
767 | | -impl<H: Default + Hasher> BuildHasher for BuildHasherDefault<H> { |
| 785 | +#[rustc_const_unstable(feature = "const_hash", issue = "104061")] |
| 786 | +impl<H: ~const Default + Hasher> const BuildHasher for BuildHasherDefault<H> { |
768 | 787 | type Hasher = H; |
769 | 788 |
|
770 | 789 | fn build_hasher(&self) -> H { |
@@ -806,14 +825,15 @@ mod impls { |
806 | 825 | macro_rules! impl_write { |
807 | 826 | ($(($ty:ident, $meth:ident),)*) => {$( |
808 | 827 | #[stable(feature = "rust1", since = "1.0.0")] |
809 | | - impl Hash for $ty { |
| 828 | + #[rustc_const_unstable(feature = "const_hash", issue = "104061")] |
| 829 | + impl const Hash for $ty { |
810 | 830 | #[inline] |
811 | | - fn hash<H: Hasher>(&self, state: &mut H) { |
| 831 | + fn hash<H: ~const Hasher>(&self, state: &mut H) { |
812 | 832 | state.$meth(*self) |
813 | 833 | } |
814 | 834 |
|
815 | 835 | #[inline] |
816 | | - fn hash_slice<H: Hasher>(data: &[$ty], state: &mut H) { |
| 836 | + fn hash_slice<H: ~const Hasher>(data: &[$ty], state: &mut H) { |
817 | 837 | let newlen = data.len() * mem::size_of::<$ty>(); |
818 | 838 | let ptr = data.as_ptr() as *const u8; |
819 | 839 | // SAFETY: `ptr` is valid and aligned, as this macro is only used |
@@ -842,54 +862,60 @@ mod impls { |
842 | 862 | } |
843 | 863 |
|
844 | 864 | #[stable(feature = "rust1", since = "1.0.0")] |
845 | | - impl Hash for bool { |
| 865 | + #[rustc_const_unstable(feature = "const_hash", issue = "104061")] |
| 866 | + impl const Hash for bool { |
846 | 867 | #[inline] |
847 | | - fn hash<H: Hasher>(&self, state: &mut H) { |
| 868 | + fn hash<H: ~const Hasher>(&self, state: &mut H) { |
848 | 869 | state.write_u8(*self as u8) |
849 | 870 | } |
850 | 871 | } |
851 | 872 |
|
852 | 873 | #[stable(feature = "rust1", since = "1.0.0")] |
853 | | - impl Hash for char { |
| 874 | + #[rustc_const_unstable(feature = "const_hash", issue = "104061")] |
| 875 | + impl const Hash for char { |
854 | 876 | #[inline] |
855 | | - fn hash<H: Hasher>(&self, state: &mut H) { |
| 877 | + fn hash<H: ~const Hasher>(&self, state: &mut H) { |
856 | 878 | state.write_u32(*self as u32) |
857 | 879 | } |
858 | 880 | } |
859 | 881 |
|
860 | 882 | #[stable(feature = "rust1", since = "1.0.0")] |
861 | | - impl Hash for str { |
| 883 | + #[rustc_const_unstable(feature = "const_hash", issue = "104061")] |
| 884 | + impl const Hash for str { |
862 | 885 | #[inline] |
863 | | - fn hash<H: Hasher>(&self, state: &mut H) { |
| 886 | + fn hash<H: ~const Hasher>(&self, state: &mut H) { |
864 | 887 | state.write_str(self); |
865 | 888 | } |
866 | 889 | } |
867 | 890 |
|
868 | 891 | #[stable(feature = "never_hash", since = "1.29.0")] |
869 | | - impl Hash for ! { |
| 892 | + #[rustc_const_unstable(feature = "const_hash", issue = "104061")] |
| 893 | + impl const Hash for ! { |
870 | 894 | #[inline] |
871 | | - fn hash<H: Hasher>(&self, _: &mut H) { |
| 895 | + fn hash<H: ~const Hasher>(&self, _: &mut H) { |
872 | 896 | *self |
873 | 897 | } |
874 | 898 | } |
875 | 899 |
|
876 | 900 | macro_rules! impl_hash_tuple { |
877 | 901 | () => ( |
878 | 902 | #[stable(feature = "rust1", since = "1.0.0")] |
879 | | - impl Hash for () { |
| 903 | + #[rustc_const_unstable(feature = "const_hash", issue = "104061")] |
| 904 | + impl const Hash for () { |
880 | 905 | #[inline] |
881 | | - fn hash<H: Hasher>(&self, _state: &mut H) {} |
| 906 | + fn hash<H: ~const Hasher>(&self, _state: &mut H) {} |
882 | 907 | } |
883 | 908 | ); |
884 | 909 |
|
885 | 910 | ( $($name:ident)+) => ( |
886 | 911 | maybe_tuple_doc! { |
887 | 912 | $($name)+ @ |
888 | 913 | #[stable(feature = "rust1", since = "1.0.0")] |
889 | | - impl<$($name: Hash),+> Hash for ($($name,)+) where last_type!($($name,)+): ?Sized { |
| 914 | + #[rustc_const_unstable(feature = "const_hash", issue = "104061")] |
| 915 | + impl<$($name: ~const Hash),+> const Hash for ($($name,)+) where last_type!($($name,)+): ?Sized { |
890 | 916 | #[allow(non_snake_case)] |
891 | 917 | #[inline] |
892 | | - fn hash<S: Hasher>(&self, state: &mut S) { |
| 918 | + fn hash<S: ~const Hasher>(&self, state: &mut S) { |
893 | 919 | let ($(ref $name,)+) = *self; |
894 | 920 | $($name.hash(state);)+ |
895 | 921 | } |
@@ -932,24 +958,27 @@ mod impls { |
932 | 958 | impl_hash_tuple! { T B C D E F G H I J K L } |
933 | 959 |
|
934 | 960 | #[stable(feature = "rust1", since = "1.0.0")] |
935 | | - impl<T: Hash> Hash for [T] { |
| 961 | + #[rustc_const_unstable(feature = "const_hash", issue = "104061")] |
| 962 | + impl<T: ~const Hash> const Hash for [T] { |
936 | 963 | #[inline] |
937 | | - fn hash<H: Hasher>(&self, state: &mut H) { |
| 964 | + fn hash<H: ~const Hasher>(&self, state: &mut H) { |
938 | 965 | state.write_length_prefix(self.len()); |
939 | 966 | Hash::hash_slice(self, state) |
940 | 967 | } |
941 | 968 | } |
942 | 969 |
|
943 | 970 | #[stable(feature = "rust1", since = "1.0.0")] |
944 | | - impl<T: ?Sized + Hash> Hash for &T { |
| 971 | + #[rustc_const_unstable(feature = "const_hash", issue = "104061")] |
| 972 | + impl<T: ?Sized + ~const Hash> const Hash for &T { |
945 | 973 | #[inline] |
946 | | - fn hash<H: Hasher>(&self, state: &mut H) { |
| 974 | + fn hash<H: ~const Hasher>(&self, state: &mut H) { |
947 | 975 | (**self).hash(state); |
948 | 976 | } |
949 | 977 | } |
950 | 978 |
|
951 | 979 | #[stable(feature = "rust1", since = "1.0.0")] |
952 | | - impl<T: ?Sized + Hash> Hash for &mut T { |
| 980 | + #[rustc_const_unstable(feature = "const_hash", issue = "104061")] |
| 981 | + impl<T: ?Sized + ~const Hash> const Hash for &mut T { |
953 | 982 | #[inline] |
954 | 983 | fn hash<H: Hasher>(&self, state: &mut H) { |
955 | 984 | (**self).hash(state); |
|
0 commit comments