@@ -217,6 +217,7 @@ let (|Nameof|_|) com ctx = function
217217 | IdentExpr ident -> Some ident.DisplayName
218218 | Get(_, ByKey( ExprKey( StringConst prop)), _, _) -> Some prop
219219 | Get(_, ByKey( FieldKey fi), _, _) -> Some fi.Name
220+ | Get(_, FieldIndex( fieldName, _), _, _) -> Some fieldName
220221 | NestedLambda( args, Call( IdentExpr ident, info, _, _), None) ->
221222 if List.sameLength args info.Args && List.zip args info.Args |> List.forall ( fun ( a1 , a2 ) ->
222223 match a2 with IdentExpr id2 -> a1.Name = id2.Name | _ -> false )
@@ -695,6 +696,50 @@ let isCompatibleWithJsComparison = function
695696// * `.GetHashCode` called directly defaults to identity hash (for reference types except string) if not implemented.
696697// * `LanguagePrimitive.PhysicalHash` creates an identity hash no matter whether GetHashCode is implemented or not.
697698
699+ let getEntityHashMethod ( com : ICompiler ) ( ent : Entity ) =
700+ if ( ent.IsFSharpUnion || ent.IsFSharpRecord) then
701+ if com.Options.EraseUnions
702+ then " Util" , " structuralHash"
703+ else " Util" , " hashSafe"
704+ elif ent.IsValueType
705+ then " Util" , " hashSafe"
706+ else " Util" , " identityHash"
707+
708+ let getEntityEqualsMethod ( com : ICompiler ) ( ent : Entity ) =
709+ if ( ent.IsFSharpUnion || ent.IsFSharpRecord) then
710+ if com.Options.EraseUnions
711+ then " Util" , " equals"
712+ else " Util" , " equalsSafe"
713+ elif ent.IsValueType
714+ then " Util" , " equalsSafe"
715+ else " Util" , " equals"
716+
717+ let getEntityCompareMethod ( com : ICompiler ) ( ent : Entity ) =
718+ if ( ent.IsFSharpUnion || ent.IsFSharpRecord) then
719+ if com.Options.EraseUnions
720+ then " Util" , " compare"
721+ else " Util" , " compareSafe"
722+ elif ent.IsValueType
723+ then " Util" , " compareSafe"
724+ else " Util" , " compare"
725+
726+ let identityHashMethod ( com : ICompiler ) = function
727+ | Boolean | Char | String | Number _ | Enum _ | Option _ | Tuple _ | List _
728+ | Builtin ( BclInt64 | BclUInt64 | BclDecimal | BclBigInt)
729+ | Builtin ( BclGuid | BclTimeSpan | BclDateTime | BclDateTimeOffset)
730+ | Builtin ( FSharpSet _ | FSharpMap _ | FSharpChoice _ | FSharpResult _) ->
731+ " Util" , " structuralHash"
732+ | DeclaredType( ent, _) -> com.GetEntity( ent) |> getEntityHashMethod com
733+ | _ -> " Util" , " identityHash"
734+
735+ let structuralHashMethod ( com : ICompiler ) = function
736+ | MetaType -> " Reflection" , " getHashCode"
737+ | DeclaredType( ent, _) ->
738+ let ent = com.GetEntity( ent)
739+ if not ent.IsInterface then getEntityHashMethod com ent
740+ else " Util" , " structuralHash"
741+ | _ -> " Util" , " structuralHash"
742+
698743let identityHash com r ( arg : Expr ) =
699744 let methodName =
700745 match arg.Type with
@@ -747,10 +792,8 @@ let rec equals (com: ICompiler) ctx r equal (left: Expr) (right: Expr) =
747792 Helper.LibCall( com, coreModFor bt, " equals" , Boolean, [ left; right], ?loc= r) |> is equal
748793 | DeclaredType( ent, _) ->
749794 let ent = com.GetEntity( ent)
750- if ent.IsFSharpUnion || ent.IsFSharpRecord || ent.IsValueType then
751- Helper.LibCall( com, " Util" , " equalsSafe" , Boolean, [ left; right], ?loc= r) |> is equal
752- else
753- Helper.LibCall( com, " Util" , " equals" , Boolean, [ left; right], ?loc= r) |> is equal
795+ let moduleName , methodName = getEntityEqualsMethod com ent
796+ Helper.LibCall( com, moduleName, methodName, Boolean, [ left; right], ?loc= r) |> is equal
754797 | Array t ->
755798 let f = makeComparerFunction com ctx t
756799 Helper.LibCall( com, " Array" , " equalsWith" , Boolean, [ f; left; right], ?loc= r) |> is equal
@@ -775,10 +818,8 @@ and compare (com: ICompiler) ctx r (left: Expr) (right: Expr) =
775818 Helper.LibCall( com, coreModFor bt, " compare" , Number Int32, [ left; right], ?loc= r)
776819 | DeclaredType( ent, _) ->
777820 let ent = com.GetEntity( ent)
778- if ent.IsFSharpUnion || ent.IsFSharpRecord || ent.IsValueType then
779- Helper.LibCall( com, " Util" , " compareSafe" , Number Int32, [ left; right], ?loc= r)
780- else
781- Helper.LibCall( com, " Util" , " compare" , Number Int32, [ left; right], ?loc= r)
821+ let moduleName , methodName = getEntityCompareMethod com ent
822+ Helper.LibCall( com, moduleName, methodName, Number Int32, [ left; right], ?loc= r)
782823 | Array t ->
783824 let f = makeComparerFunction com ctx t
784825 Helper.LibCall( com, " Array" , " compareWith" , Number Int32, [ f; left; right], ?loc= r)
0 commit comments