summaryrefslogtreecommitdiffstats
path: root/library/core/src/hash
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:32 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:32 +0000
commit4547b622d8d29df964fa2914213088b148c498fc (patch)
tree9fc6b25f3c3add6b745be9a2400a6e96140046e9 /library/core/src/hash
parentReleasing progress-linux version 1.66.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-4547b622d8d29df964fa2914213088b148c498fc.tar.xz
rustc-4547b622d8d29df964fa2914213088b148c498fc.zip
Merging upstream version 1.67.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/core/src/hash')
-rw-r--r--library/core/src/hash/mod.rs83
-rw-r--r--library/core/src/hash/sip.rs36
2 files changed, 78 insertions, 41 deletions
diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs
index aa13435e6..c755afa39 100644
--- a/library/core/src/hash/mod.rs
+++ b/library/core/src/hash/mod.rs
@@ -86,7 +86,8 @@
#![stable(feature = "rust1", since = "1.0.0")]
use crate::fmt;
-use crate::marker;
+use crate::intrinsics::const_eval_select;
+use crate::marker::{self, Destruct};
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
@@ -183,6 +184,7 @@ mod sip;
/// [impl]: ../../std/primitive.str.html#impl-Hash-for-str
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "Hash"]
+#[const_trait]
pub trait Hash {
/// Feeds this value into the given [`Hasher`].
///
@@ -234,13 +236,25 @@ pub trait Hash {
/// [`hash`]: Hash::hash
/// [`hash_slice`]: Hash::hash_slice
#[stable(feature = "hash_slice", since = "1.3.0")]
- fn hash_slice<H: Hasher>(data: &[Self], state: &mut H)
+ fn hash_slice<H: ~const Hasher>(data: &[Self], state: &mut H)
where
Self: Sized,
{
- for piece in data {
- piece.hash(state);
+ //FIXME(const_trait_impl): revert to only a for loop
+ fn rt<T: Hash, H: Hasher>(data: &[T], state: &mut H) {
+ for piece in data {
+ piece.hash(state)
+ }
+ }
+ const fn ct<T: ~const Hash, H: ~const Hasher>(data: &[T], state: &mut H) {
+ let mut i = 0;
+ while i < data.len() {
+ data[i].hash(state);
+ i += 1;
+ }
}
+ // SAFETY: same behavior, CT just uses while instead of for
+ unsafe { const_eval_select((data, state), ct, rt) };
}
}
@@ -313,6 +327,7 @@ pub use macros::Hash;
/// [`write_u8`]: Hasher::write_u8
/// [`write_u32`]: Hasher::write_u32
#[stable(feature = "rust1", since = "1.0.0")]
+#[const_trait]
pub trait Hasher {
/// Returns the hash value for the values written so far.
///
@@ -558,7 +573,8 @@ pub trait Hasher {
}
#[stable(feature = "indirect_hasher_impl", since = "1.22.0")]
-impl<H: Hasher + ?Sized> Hasher for &mut H {
+#[rustc_const_unstable(feature = "const_hash", issue = "104061")]
+impl<H: ~const Hasher + ?Sized> const Hasher for &mut H {
fn finish(&self) -> u64 {
(**self).finish()
}
@@ -638,6 +654,7 @@ impl<H: Hasher + ?Sized> Hasher for &mut H {
/// [`build_hasher`]: BuildHasher::build_hasher
/// [`HashMap`]: ../../std/collections/struct.HashMap.html
#[stable(since = "1.7.0", feature = "build_hasher")]
+#[const_trait]
pub trait BuildHasher {
/// Type of the hasher that will be created.
#[stable(since = "1.7.0", feature = "build_hasher")]
@@ -698,9 +715,10 @@ pub trait BuildHasher {
/// );
/// ```
#[unstable(feature = "build_hasher_simple_hash_one", issue = "86161")]
- fn hash_one<T: Hash>(&self, x: T) -> u64
+ fn hash_one<T: ~const Hash + ~const Destruct>(&self, x: T) -> u64
where
Self: Sized,
+ Self::Hasher: ~const Hasher + ~const Destruct,
{
let mut hasher = self.build_hasher();
x.hash(&mut hasher);
@@ -764,7 +782,8 @@ impl<H> fmt::Debug for BuildHasherDefault<H> {
}
#[stable(since = "1.7.0", feature = "build_hasher")]
-impl<H: Default + Hasher> BuildHasher for BuildHasherDefault<H> {
+#[rustc_const_unstable(feature = "const_hash", issue = "104061")]
+impl<H: ~const Default + Hasher> const BuildHasher for BuildHasherDefault<H> {
type Hasher = H;
fn build_hasher(&self) -> H {
@@ -806,14 +825,15 @@ mod impls {
macro_rules! impl_write {
($(($ty:ident, $meth:ident),)*) => {$(
#[stable(feature = "rust1", since = "1.0.0")]
- impl Hash for $ty {
+ #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
+ impl const Hash for $ty {
#[inline]
- fn hash<H: Hasher>(&self, state: &mut H) {
+ fn hash<H: ~const Hasher>(&self, state: &mut H) {
state.$meth(*self)
}
#[inline]
- fn hash_slice<H: Hasher>(data: &[$ty], state: &mut H) {
+ fn hash_slice<H: ~const Hasher>(data: &[$ty], state: &mut H) {
let newlen = data.len() * mem::size_of::<$ty>();
let ptr = data.as_ptr() as *const u8;
// SAFETY: `ptr` is valid and aligned, as this macro is only used
@@ -842,33 +862,37 @@ mod impls {
}
#[stable(feature = "rust1", since = "1.0.0")]
- impl Hash for bool {
+ #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
+ impl const Hash for bool {
#[inline]
- fn hash<H: Hasher>(&self, state: &mut H) {
+ fn hash<H: ~const Hasher>(&self, state: &mut H) {
state.write_u8(*self as u8)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
- impl Hash for char {
+ #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
+ impl const Hash for char {
#[inline]
- fn hash<H: Hasher>(&self, state: &mut H) {
+ fn hash<H: ~const Hasher>(&self, state: &mut H) {
state.write_u32(*self as u32)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
- impl Hash for str {
+ #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
+ impl const Hash for str {
#[inline]
- fn hash<H: Hasher>(&self, state: &mut H) {
+ fn hash<H: ~const Hasher>(&self, state: &mut H) {
state.write_str(self);
}
}
#[stable(feature = "never_hash", since = "1.29.0")]
- impl Hash for ! {
+ #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
+ impl const Hash for ! {
#[inline]
- fn hash<H: Hasher>(&self, _: &mut H) {
+ fn hash<H: ~const Hasher>(&self, _: &mut H) {
*self
}
}
@@ -876,9 +900,10 @@ mod impls {
macro_rules! impl_hash_tuple {
() => (
#[stable(feature = "rust1", since = "1.0.0")]
- impl Hash for () {
+ #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
+ impl const Hash for () {
#[inline]
- fn hash<H: Hasher>(&self, _state: &mut H) {}
+ fn hash<H: ~const Hasher>(&self, _state: &mut H) {}
}
);
@@ -886,10 +911,11 @@ mod impls {
maybe_tuple_doc! {
$($name)+ @
#[stable(feature = "rust1", since = "1.0.0")]
- impl<$($name: Hash),+> Hash for ($($name,)+) where last_type!($($name,)+): ?Sized {
+ #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
+ impl<$($name: ~const Hash),+> const Hash for ($($name,)+) where last_type!($($name,)+): ?Sized {
#[allow(non_snake_case)]
#[inline]
- fn hash<S: Hasher>(&self, state: &mut S) {
+ fn hash<S: ~const Hasher>(&self, state: &mut S) {
let ($(ref $name,)+) = *self;
$($name.hash(state);)+
}
@@ -932,24 +958,27 @@ mod impls {
impl_hash_tuple! { T B C D E F G H I J K L }
#[stable(feature = "rust1", since = "1.0.0")]
- impl<T: Hash> Hash for [T] {
+ #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
+ impl<T: ~const Hash> const Hash for [T] {
#[inline]
- fn hash<H: Hasher>(&self, state: &mut H) {
+ fn hash<H: ~const Hasher>(&self, state: &mut H) {
state.write_length_prefix(self.len());
Hash::hash_slice(self, state)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
- impl<T: ?Sized + Hash> Hash for &T {
+ #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
+ impl<T: ?Sized + ~const Hash> const Hash for &T {
#[inline]
- fn hash<H: Hasher>(&self, state: &mut H) {
+ fn hash<H: ~const Hasher>(&self, state: &mut H) {
(**self).hash(state);
}
}
#[stable(feature = "rust1", since = "1.0.0")]
- impl<T: ?Sized + Hash> Hash for &mut T {
+ #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
+ impl<T: ?Sized + ~const Hash> const Hash for &mut T {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
(**self).hash(state);
diff --git a/library/core/src/hash/sip.rs b/library/core/src/hash/sip.rs
index 81bf1dfdf..7f8287bf5 100644
--- a/library/core/src/hash/sip.rs
+++ b/library/core/src/hash/sip.rs
@@ -118,7 +118,7 @@ macro_rules! load_int_le {
/// Safety: this performs unchecked indexing of `buf` at `start..start+len`, so
/// that must be in-bounds.
#[inline]
-unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 {
+const unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 {
debug_assert!(len < 8);
let mut i = 0; // current byte index (from LSB) in the output u64
let mut out = 0;
@@ -138,7 +138,8 @@ unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 {
out |= (unsafe { *buf.get_unchecked(start + i) } as u64) << (i * 8);
i += 1;
}
- debug_assert_eq!(i, len);
+ //FIXME(fee1-dead): use debug_assert_eq
+ debug_assert!(i == len);
out
}
@@ -150,8 +151,9 @@ impl SipHasher {
since = "1.13.0",
note = "use `std::collections::hash_map::DefaultHasher` instead"
)]
+ #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
#[must_use]
- pub fn new() -> SipHasher {
+ pub const fn new() -> SipHasher {
SipHasher::new_with_keys(0, 0)
}
@@ -162,8 +164,9 @@ impl SipHasher {
since = "1.13.0",
note = "use `std::collections::hash_map::DefaultHasher` instead"
)]
+ #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
#[must_use]
- pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
+ pub const fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
SipHasher(SipHasher24 { hasher: Hasher::new_with_keys(key0, key1) })
}
}
@@ -176,7 +179,8 @@ impl SipHasher13 {
since = "1.13.0",
note = "use `std::collections::hash_map::DefaultHasher` instead"
)]
- pub fn new() -> SipHasher13 {
+ #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
+ pub const fn new() -> SipHasher13 {
SipHasher13::new_with_keys(0, 0)
}
@@ -187,14 +191,15 @@ impl SipHasher13 {
since = "1.13.0",
note = "use `std::collections::hash_map::DefaultHasher` instead"
)]
- pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 {
+ #[rustc_const_unstable(feature = "const_hash", issue = "104061")]
+ pub const fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 {
SipHasher13 { hasher: Hasher::new_with_keys(key0, key1) }
}
}
impl<S: Sip> Hasher<S> {
#[inline]
- fn new_with_keys(key0: u64, key1: u64) -> Hasher<S> {
+ const fn new_with_keys(key0: u64, key1: u64) -> Hasher<S> {
let mut state = Hasher {
k0: key0,
k1: key1,
@@ -209,7 +214,7 @@ impl<S: Sip> Hasher<S> {
}
#[inline]
- fn reset(&mut self) {
+ const fn reset(&mut self) {
self.length = 0;
self.state.v0 = self.k0 ^ 0x736f6d6570736575;
self.state.v1 = self.k1 ^ 0x646f72616e646f6d;
@@ -220,7 +225,8 @@ impl<S: Sip> Hasher<S> {
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl super::Hasher for SipHasher {
+#[rustc_const_unstable(feature = "const_hash", issue = "104061")]
+impl const super::Hasher for SipHasher {
#[inline]
fn write(&mut self, msg: &[u8]) {
self.0.hasher.write(msg)
@@ -238,7 +244,8 @@ impl super::Hasher for SipHasher {
}
#[unstable(feature = "hashmap_internals", issue = "none")]
-impl super::Hasher for SipHasher13 {
+#[rustc_const_unstable(feature = "const_hash", issue = "104061")]
+impl const super::Hasher for SipHasher13 {
#[inline]
fn write(&mut self, msg: &[u8]) {
self.hasher.write(msg)
@@ -255,7 +262,7 @@ impl super::Hasher for SipHasher13 {
}
}
-impl<S: Sip> super::Hasher for Hasher<S> {
+impl<S: ~const Sip> const super::Hasher for Hasher<S> {
// Note: no integer hashing methods (`write_u*`, `write_i*`) are defined
// for this type. We could add them, copy the `short_write` implementation
// in librustc_data_structures/sip128.rs, and add `write_u*`/`write_i*`
@@ -335,7 +342,7 @@ impl<S: Sip> super::Hasher for Hasher<S> {
}
}
-impl<S: Sip> Clone for Hasher<S> {
+impl<S: Sip> const Clone for Hasher<S> {
#[inline]
fn clone(&self) -> Hasher<S> {
Hasher {
@@ -359,6 +366,7 @@ impl<S: Sip> Default for Hasher<S> {
}
#[doc(hidden)]
+#[const_trait]
trait Sip {
fn c_rounds(_: &mut State);
fn d_rounds(_: &mut State);
@@ -367,7 +375,7 @@ trait Sip {
#[derive(Debug, Clone, Default)]
struct Sip13Rounds;
-impl Sip for Sip13Rounds {
+impl const Sip for Sip13Rounds {
#[inline]
fn c_rounds(state: &mut State) {
compress!(state);
@@ -384,7 +392,7 @@ impl Sip for Sip13Rounds {
#[derive(Debug, Clone, Default)]
struct Sip24Rounds;
-impl Sip for Sip24Rounds {
+impl const Sip for Sip24Rounds {
#[inline]
fn c_rounds(state: &mut State) {
compress!(state);