Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/Compiler/Checking/OverloadResolutionCache.fs
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,12 @@ let tryGetTypeStructureForOverloadCache (g: TcGlobals) (ty: TType) : TypeStructu
let ty = stripTyEqns g ty

match tryGetTypeStructureOfStrippedType ty with
| ValueSome(Stable tokens) -> ValueSome(Stable tokens)
| ValueSome(Unstable tokens) ->
| ValueSome(Stable(h, tokens)) -> ValueSome(Stable(h, tokens))
| ValueSome(Unstable(h, tokens)) ->
if hasUnsolvedTokens tokens then
ValueNone
else
ValueSome(Stable tokens)
ValueSome(Stable(h, tokens))
| ValueSome PossiblyInfinite -> ValueNone
| ValueNone -> ValueNone

Expand Down Expand Up @@ -162,8 +162,8 @@ let tryComputeOverloadCacheKey
| Some retTy ->
match tryGetTypeStructureForOverloadCache g retTy with
| ValueSome ts -> ValueSome ts
| ValueNone -> if anyHasOutArgs then ValueNone else ValueSome(Stable [||])
| None -> ValueSome(Stable [||])
| ValueNone -> if anyHasOutArgs then ValueNone else ValueSome(Stable(0, [||]))
| None -> ValueSome(Stable(0, [||]))

match retTyStructure with
| ValueNone -> ValueNone
Expand Down
34 changes: 30 additions & 4 deletions src/Compiler/Utilities/TypeHashing.fs
Original file line number Diff line number Diff line change
Expand Up @@ -407,12 +407,35 @@ module StructuralUtilities =
| Unsolved of int
| Rigid of int

let private hashTokenArray (tokens: TypeToken[]) =
let mutable acc = 0
for t in tokens do
acc <- combineHash acc (hash t)
acc

[<CustomEquality; NoComparison>]
type TypeStructure =
| Stable of TypeToken[]
| Stable of hash: int * tokens: TypeToken[]
// Unstable means that the type structure of a given TType may change because of constraint solving or Trace.Undo.
| Unstable of TypeToken[]
| Unstable of hash: int * tokens: TypeToken[]
| PossiblyInfinite

override this.GetHashCode() =
match this with
| Stable(h, _) -> h
| Unstable(h, _) -> h ||| 0x40000000
| PossiblyInfinite -> 0

override this.Equals(obj) =
match obj with
| :? TypeStructure as other ->
match this, other with
| Stable(h1, a), Stable(h2, b) -> h1 = h2 && a = b
| Unstable(h1, a), Unstable(h2, b) -> h1 = h2 && a = b
| PossiblyInfinite, PossiblyInfinite -> true
| _ -> false
| _ -> false

type private GenerationContext() =
member val TyparMap = System.Collections.Generic.Dictionary<Stamp, int>(4)
member val Tokens = ResizeArray<TypeToken>(MaxTokenCount)
Expand Down Expand Up @@ -566,8 +589,11 @@ module StructuralUtilities =

// If the sequence got too long, just drop it, we could be dealing with an infinite type.
if out.Count >= MaxTokenCount then PossiblyInfinite
elif not ctx.Stable then Unstable(out.ToArray())
else Stable(out.ToArray())
else
let tokens = out.ToArray()
let h = hashTokenArray tokens
if not ctx.Stable then Unstable(h, tokens)
else Stable(h, tokens)

// Speed up repeated calls by memoizing results for types that yield a stable structure.
let private getTypeStructureOfStrippedType =
Expand Down
Loading