Skip to content

Commit 4662a06

Browse files
forkibaronfel
authored andcommitted
Reduce isAppTy calls in TypeDefinitelyHasEquality (#8286)
1 parent 2a5a02f commit 4662a06

File tree

1 file changed

+24
-19
lines changed

1 file changed

+24
-19
lines changed

src/fsharp/AugmentWithHashCompare.fs

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,23 +1075,28 @@ let MakeBindingsForEqualsAugmentation (g: TcGlobals) (tycon: Tycon) =
10751075
elif tycon.IsRecordTycon || tycon.IsStructOrEnumTycon then mkEquals mkRecdEquality
10761076
else []
10771077

1078-
let rec TypeDefinitelyHasEquality g ty =
1079-
if isAppTy g ty && HasFSharpAttribute g g.attrib_NoEqualityAttribute (tcrefOfAppTy g ty).Attribs then
1078+
let rec TypeDefinitelyHasEquality g ty =
1079+
let appTy = tryAppTy g ty
1080+
match appTy with
1081+
| ValueSome(tcref,_) when HasFSharpAttribute g g.attrib_NoEqualityAttribute tcref.Attribs ->
10801082
false
1081-
elif isTyparTy g ty &&
1082-
(destTyparTy g ty).Constraints |> List.exists (function TyparConstraint.SupportsEquality _ -> true | _ -> false) then
1083-
true
1084-
else
1085-
match ty with
1086-
| SpecialEquatableHeadType g tinst ->
1087-
tinst |> List.forall (TypeDefinitelyHasEquality g)
1088-
| SpecialNotEquatableHeadType g _ ->
1089-
false
1090-
| _ ->
1091-
// The type is equatable because it has Object.Equals(...)
1092-
isAppTy g ty &&
1093-
let tcref, tinst = destAppTy g ty
1094-
// Give a good error for structural types excluded from the equality relation because of their fields
1095-
not (TyconIsCandidateForAugmentationWithEquals g tcref.Deref && Option.isNone tcref.GeneratedHashAndEqualsWithComparerValues) &&
1096-
// Check the (possibly inferred) structural dependencies
1097-
(tinst, tcref.TyparsNoRange) ||> List.lengthsEqAndForall2 (fun ty tp -> not tp.EqualityConditionalOn || TypeDefinitelyHasEquality g ty)
1083+
| _ ->
1084+
if isTyparTy g ty &&
1085+
(destTyparTy g ty).Constraints |> List.exists (function TyparConstraint.SupportsEquality _ -> true | _ -> false) then
1086+
true
1087+
else
1088+
match ty with
1089+
| SpecialEquatableHeadType g tinst ->
1090+
tinst |> List.forall (TypeDefinitelyHasEquality g)
1091+
| SpecialNotEquatableHeadType g _ ->
1092+
false
1093+
| _ ->
1094+
// The type is equatable because it has Object.Equals(...)
1095+
match appTy with
1096+
| ValueSome(tcref,tinst) ->
1097+
// Give a good error for structural types excluded from the equality relation because of their fields
1098+
not (TyconIsCandidateForAugmentationWithEquals g tcref.Deref && Option.isNone tcref.GeneratedHashAndEqualsWithComparerValues) &&
1099+
// Check the (possibly inferred) structural dependencies
1100+
(tinst, tcref.TyparsNoRange)
1101+
||> List.lengthsEqAndForall2 (fun ty tp -> not tp.EqualityConditionalOn || TypeDefinitelyHasEquality g ty)
1102+
| _ -> false

0 commit comments

Comments
 (0)