|
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