Skip to content

Commit 6f0c46f

Browse files
committed
fix: [Rust] Update hashing tests
1 parent d14c13e commit 6f0c46f

16 files changed

Lines changed: 851 additions & 160 deletions

File tree

src/Fable.Transforms/Rust/Fable2Rust.fs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4956,7 +4956,7 @@ module Util =
49564956

49574957
let makeRefEqualityTraitImpls com ctx entName genArgs =
49584958
// For F# class types without structural equality, use pointer-based
4959-
// PartialEq, Eq, and Hash so they can be used as HashSet/HashMap keys
4959+
// PartialEq, Eq, Hash, and Hashable so they can be used as HashSet/HashMap keys
49604960
// with reference (pointer) equality semantics, matching .NET behavior.
49614961
// expected output:
49624962
// impl PartialEq for {self_ty} {
@@ -4968,6 +4968,9 @@ module Util =
49684968
// core::hash::Hash::hash(&(self as *const Self as usize), state)
49694969
// }
49704970
// }
4971+
// impl Native_::Hashable for {self_ty} {
4972+
// fn getHashCode(&self) -> i32 { Native_::referenceHash(self) }
4973+
// }
49714974

49724975
let eqFnItem =
49734976
let bodyStmt = "core::ptr::eq(self, other)" |> mkEmitExprStmt
@@ -5009,10 +5012,24 @@ module Util =
50095012
let fnKind = mkFnKind DEFAULT_FN_HEADER fnDecl generics fnBody
50105013
mkFnAssocItem [] "hash" fnKind
50115014

5015+
let getHashCodeFnItem =
5016+
let referenceHashName = getLibraryImportName com ctx "Native" "referenceHash"
5017+
let bodyStmt = $"{referenceHashName}(self)" |> mkEmitExprStmt
5018+
let fnBody = [ bodyStmt ] |> mkBlock |> Some
5019+
5020+
let fnDecl =
5021+
let inputs = [ mkImplSelfParam false false ]
5022+
let output = mkGenericPathTy [ "i32" ] None |> mkFnRetTy
5023+
mkFnDecl inputs output
5024+
5025+
let fnKind = mkFnKind DEFAULT_FN_HEADER fnDecl NO_GENERICS fnBody
5026+
mkFnAssocItem [ mkAttr "inline" [] ] "getHashCode" fnKind
5027+
50125028
[
50135029
makeImpl ("core" :: "cmp" :: rawIdent "PartialEq" :: []) [ eqFnItem ]
50145030
makeImpl ("core" :: "cmp" :: rawIdent "Eq" :: []) []
50155031
makeImpl ("core" :: "hash" :: "Hash" :: []) [ hashFnItem ]
5032+
makeImpl (getLibraryImportName com ctx "Native" "Hashable" |> splitNameParts) [ getHashCodeFnItem ]
50165033
]
50175034

50185035
let op_impl_map =

src/fable-library-rust/src/BigInt.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
pub mod BigInt_ {
33
use crate::Decimal_::{decimal, truncate};
44
use crate::NativeArray_::{array_from, Array};
5-
use crate::Native_::{compare, Lrc, MutCell, ToString, Vec};
5+
use crate::Native_::{compare, getHashCode, Hashable, Lrc, MutCell, ToString, Vec};
66
use crate::String_::{string, toString as toString_1};
77

88
use num_bigint::*;
@@ -33,6 +33,13 @@ pub mod BigInt_ {
3333
}
3434
}
3535

36+
impl Hashable for bigint {
37+
#[inline]
38+
fn getHashCode(&self) -> i32 {
39+
getHashCode(self)
40+
}
41+
}
42+
3643
macro_rules! un_op {
3744
($op_trait:ident, $op_fn:ident, $op:tt) => {
3845
impl core::ops::$op_trait for bigint {

src/fable-library-rust/src/DateOnly.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
pub mod DateOnly_ {
33
use crate::{
44
DateTime_::{ticks_to_duration, DateTime, DateTimeKind},
5-
Native_::{compare, MutCell, ToString},
5+
Native_::{compare, getHashCode, Hashable, MutCell, ToString},
66
String_::{fromString, string},
77
TimeOnly_::TimeOnly,
88
TimeSpan_::ticks_per_day,
@@ -19,6 +19,13 @@ pub mod DateOnly_ {
1919
}
2020
}
2121

22+
impl Hashable for DateOnly {
23+
#[inline]
24+
fn getHashCode(&self) -> i32 {
25+
getHashCode(self)
26+
}
27+
}
28+
2229
pub fn compareTo(x: DateOnly, y: DateOnly) -> i32 {
2330
compare(&x, &y)
2431
}

src/fable-library-rust/src/DateTime.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ pub mod DateTime_ {
33
use crate::{
44
DateOnly_::DateOnly,
55
DateTimeOffset_::DateTimeOffset,
6-
Native_::{compare, MutCell, ToString},
6+
Native_::{compare, getHashCode, Hashable, MutCell, ToString},
77
String_::{fromString, string},
88
TimeOnly_::TimeOnly,
99
TimeSpan_::{nanoseconds_per_tick, ticks_per_second, TimeSpan},
@@ -45,6 +45,13 @@ pub mod DateTime_ {
4545
}
4646
}
4747

48+
impl Hashable for DateTime {
49+
#[inline]
50+
fn getHashCode(&self) -> i32 {
51+
getHashCode(&self.ticks())
52+
}
53+
}
54+
4855
pub fn compareTo(x: DateTime, y: DateTime) -> i32 {
4956
compare(&x.ticks(), &y.ticks())
5057
}

src/fable-library-rust/src/DateTimeOffset.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ pub mod DateTimeOffset_ {
33
use crate::{
44
DateOnly_::DateOnly,
55
DateTime_::{duration_to_ticks, ticks_to_duration, DateTime, DateTimeKind},
6-
Native_::{compare, MutCell, ToString},
6+
Native_::{compare, getHashCode, Hashable, MutCell, ToString},
77
String_::{fromString, string},
88
TimeOnly_::TimeOnly,
99
TimeSpan_::{
@@ -38,6 +38,13 @@ pub mod DateTimeOffset_ {
3838
}
3939
}
4040

41+
impl Hashable for DateTimeOffset {
42+
#[inline]
43+
fn getHashCode(&self) -> i32 {
44+
getHashCode(&self.utcTicks())
45+
}
46+
}
47+
4148
pub fn compareTo(x: DateTimeOffset, y: DateTimeOffset) -> i32 {
4249
compare(&x.utcDateTime(), &y.utcDateTime())
4350
}

src/fable-library-rust/src/Decimal.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#[cfg(feature = "decimal")]
22
pub mod Decimal_ {
3-
use crate::Native_::{compare, Lrc, MutCell, Vec};
3+
use crate::Native_::{compare, getHashCode, Hashable, Lrc, MutCell, Vec};
44
use crate::NativeArray_::{new_array, Array};
55
use crate::String_::{string, toString as toString_1};
66
use core::cmp::Ordering;
@@ -14,6 +14,13 @@ pub mod Decimal_ {
1414
pub const MaxValue: decimal = Decimal::MAX;
1515
pub const MinValue: decimal = Decimal::MIN;
1616

17+
impl Hashable for decimal {
18+
#[inline]
19+
fn getHashCode(&self) -> i32 {
20+
getHashCode(self)
21+
}
22+
}
23+
1724
pub fn equals(x: decimal, y: decimal) -> bool { x.eq(&y) }
1825
pub fn compareTo(x: decimal, y: decimal) -> i32 { compare(&x, &y) }
1926

src/fable-library-rust/src/Guid.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
pub mod Guid_ {
33
use crate::DateTimeOffset_::DateTimeOffset;
44
use crate::NativeArray_::{new_array, Array};
5-
use crate::Native_::{compare, MutCell};
5+
use crate::Native_::{compare, getHashCode, Hashable, MutCell};
66
use crate::String_::{string, toString};
77
use uuid::{NoContext, Timestamp, Uuid};
88

@@ -17,6 +17,14 @@ pub mod Guid_ {
1717
}
1818
}
1919

20+
impl Hashable for Guid {
21+
#[inline]
22+
fn getHashCode(&self) -> i32 {
23+
let bytes = toByteArray(*self);
24+
getHashCode(&bytes.as_slice())
25+
}
26+
}
27+
2028
pub fn compareTo(x: Guid, y: Guid) -> i32 {
2129
compare(&x, &y)
2230
}

src/fable-library-rust/src/Interop.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ pub mod ListExt {
7575
}
7676

7777
pub mod SetExt {
78-
use crate::Native_::{Func2, Hashable, NullableRef, Vec, make_compare, seq_to_iter};
78+
use crate::Native_::{Func2, Hashable, NullableRef, Vec, combineHashCodes, make_compare, seq_to_iter};
7979
use crate::Set_::{Set, add, compareTo, empty, equals, isEmpty, toSeq};
8080
use core::cmp::Ordering;
8181
use core::hash::{Hash, Hasher};
@@ -113,6 +113,17 @@ pub mod SetExt {
113113

114114
impl<T: Clone + Hashable + PartialOrd> Eq for Set<T> {}
115115

116+
impl<T: Clone + Hashable + PartialOrd> Hashable for Set<T> {
117+
fn getHashCode(&self) -> i32 {
118+
let s = toSeq(self.clone());
119+
let mut res = 0_i32;
120+
for value in seq_to_iter(s) {
121+
res = combineHashCodes(res, value.getHashCode());
122+
}
123+
res
124+
}
125+
}
126+
116127
impl<T: Clone + Hashable + PartialOrd + Hash> Hash for Set<T> {
117128
fn hash<H: Hasher>(&self, state: &mut H) {
118129
let s = toSeq(self.clone());
@@ -171,7 +182,7 @@ pub mod SetExt {
171182

172183
pub mod MapExt {
173184
use crate::Map_::{Map, add, compareTo, empty, equals, isEmpty, iterate, toSeq};
174-
use crate::Native_::{Func2, Hashable, NullableRef, Vec, make_compare, seq_to_iter};
185+
use crate::Native_::{Func2, Hashable, NullableRef, Vec, combineHashCodes, make_compare, seq_to_iter};
175186
use core::cmp::Ordering;
176187
use core::hash::{Hash, Hasher};
177188

@@ -208,6 +219,19 @@ pub mod MapExt {
208219

209220
impl<K: Clone + Hashable + PartialOrd, V: Clone + Hashable + PartialOrd> Eq for Map<K, V> {}
210221

222+
impl<K: Clone + Hashable + PartialOrd, V: Clone + Hashable + PartialOrd> Hashable for Map<K, V> {
223+
fn getHashCode(&self) -> i32 {
224+
let s = toSeq(self.clone());
225+
let mut res = 0_i32;
226+
for kvp in seq_to_iter(s) {
227+
let (key, value) = kvp.as_ref();
228+
res = combineHashCodes(res, key.getHashCode());
229+
res = combineHashCodes(res, value.getHashCode());
230+
}
231+
res
232+
}
233+
}
234+
211235
impl<K: Clone + Hashable + PartialOrd + Hash, V: Clone + Hash> Hash for Map<K, V> {
212236
fn hash<H: Hasher>(&self, state: &mut H) {
213237
let s = toSeq(self.clone());

src/fable-library-rust/src/LrcPtr.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::Native_::{Any, Lrc, NullableRef};
1+
use crate::Native_::{Any, Hashable, Lrc, NullableRef};
22
use core::cmp::Ordering;
33
use core::hash::{Hash, Hasher};
44
use core::ops::*;
@@ -48,6 +48,13 @@ impl<T: ?Sized> Clone for LrcPtr<T> {
4848
}
4949
}
5050

51+
impl<T: Hashable + ?Sized> Hashable for LrcPtr<T> {
52+
#[inline]
53+
fn getHashCode(&self) -> i32 {
54+
self.0.as_ref().map_or(0, |value| value.getHashCode())
55+
}
56+
}
57+
5158
impl<T: ?Sized> Deref for LrcPtr<T> {
5259
type Target = Lrc<T>;
5360

0 commit comments

Comments
 (0)