@@ -359,32 +359,23 @@ module HashTastMemberOrVals =
359
359
| Some _ -> hashMember ( g, obs) emptyTyparInst vref.Deref
360
360
361
361
/// Lossless accumulation of TType structure
362
- module TypeStructural =
363
- // Helper struct whose instances are never equal (even to themselves).
362
+ module StructuralUtilities =
364
363
[<Struct; CustomEquality; NoComparison>]
365
364
type NeverEqual =
366
365
struct
367
366
interface System.IEquatable< NeverEqual> with
368
367
member _.Equals _ = false
369
-
370
- override _.Equals ( _ ) = false
368
+ override _.Equals _ = false
371
369
override _.GetHashCode () = 0
372
370
end
373
371
374
- [<Struct; NoComparison>]
372
+ [<Struct; NoComparison; RequireQualifiedAccess >]
375
373
type NullnessToken =
376
374
| Known of info : NullnessInfo
377
375
| Variable of never : NeverEqual
378
376
| Absent
379
377
380
- /// Convert compiler Nullness info to token form
381
- let inline toNullnessToken ( n : Nullness ) =
382
- match n with
383
- | Nullness.Known k -> NullnessToken.Known k
384
- | Nullness.Variable _ -> NullnessToken.Variable( NeverEqual())
385
-
386
- /// Tokens capturing a lossless, structural representation of TType needed for deterministic keys.
387
- [<Struct; NoComparison>]
378
+ [<Struct; NoComparison; RequireQualifiedAccess>]
388
379
type TypeToken =
389
380
| Stamp of stamp : Stamp
390
381
| UCase of name : string
@@ -395,59 +386,70 @@ module TypeStructural =
395
386
396
387
type TypeStructure = TypeToken[]
397
388
398
- /// Accumulate Measure to MeasureToken
399
- let rec private accumulateMeasure m acc =
389
+ [<Literal>]
390
+ let private initialTokenCapacity = 4
391
+
392
+ // Single reusable token for Nullness.Variable
393
+ let private neverEqual = NullnessToken.Variable( NeverEqual())
394
+
395
+ let inline toNullnessToken ( n : Nullness ) =
396
+ match n with
397
+ | Nullness.Known k -> NullnessToken.Known k
398
+ // If nullness is not known we must treat the types as not equal for caching purposes.
399
+ | Nullness.Variable _ -> neverEqual
400
+
401
+ let rec private accumulateMeasure ( tokens : ResizeArray < TypeToken >) ( m : Measure ) =
400
402
match m with
401
- | Measure.Var mv -> acc ( Stamp mv.Stamp)
402
- | Measure.Const( tcref, _) -> acc ( Stamp tcref.Stamp)
403
+ | Measure.Var mv ->
404
+ tokens.Add( TypeToken.Stamp mv.Stamp)
405
+ | Measure.Const( tcref, _) ->
406
+ tokens.Add( TypeToken.Stamp tcref.Stamp)
403
407
| Measure.Prod( m1, m2, _) ->
404
- accumulateMeasure m1 acc
405
- accumulateMeasure m2 acc
406
- | Measure.Inv m1 -> accumulateMeasure m1 acc
407
- | Measure.One _ -> acc MeasureOne
408
+ accumulateMeasure tokens m1
409
+ accumulateMeasure tokens m2
410
+ | Measure.Inv m1 ->
411
+ accumulateMeasure tokens m1
412
+ | Measure.One _ ->
413
+ tokens.Add( TypeToken.MeasureOne)
408
414
| Measure.RationalPower( m1, r) ->
409
- accumulateMeasure m1 acc
410
- acc ( MeasureRational r)
415
+ accumulateMeasure tokens m1
416
+ tokens.Add ( TypeToken. MeasureRational r)
411
417
412
- /// Accumulate a TType into a lossless token list. Uses stamps for identity where appropriate (matching hashTType logic).
413
- let rec private accumulateTType ( ty : TType ) acc =
418
+ let rec private accumulateTType ( tokens : ResizeArray < TypeToken >) ( ty : TType ) =
414
419
match ty with
415
420
| TType_ ucase( u, tinst) ->
416
- acc ( UCase u.CaseName)
417
-
421
+ tokens.Add( TypeToken.UCase u.CaseName)
418
422
for arg in tinst do
419
- accumulateTType arg acc
423
+ accumulateTType tokens arg
420
424
| TType_ app( tcref, tinst, n) ->
421
- acc ( Stamp tcref.Stamp)
422
- acc ( Nullness( toNullnessToken n))
423
-
425
+ tokens.Add( TypeToken.Stamp tcref.Stamp)
426
+ tokens.Add( TypeToken.Nullness( toNullnessToken n))
424
427
for arg in tinst do
425
- accumulateTType arg acc
428
+ accumulateTType tokens arg
426
429
| TType_ anon( info, tys) ->
427
- acc ( Stamp info.Stamp)
428
-
430
+ tokens.Add( TypeToken.Stamp info.Stamp)
429
431
for arg in tys do
430
- accumulateTType arg acc
432
+ accumulateTType tokens arg
431
433
| TType_ tuple( tupInfo, tys) ->
432
- acc ( TupInfo( evalTupInfoIsStruct tupInfo))
433
-
434
+ tokens.Add( TypeToken.TupInfo( evalTupInfoIsStruct tupInfo))
434
435
for arg in tys do
435
- accumulateTType arg acc
436
+ accumulateTType tokens arg
436
437
| TType_ forall( tps, tau) ->
437
438
for tp in tps do
438
- acc ( Stamp tp.Stamp)
439
-
440
- accumulateTType tau acc
439
+ tokens.Add( TypeToken.Stamp tp.Stamp)
440
+ accumulateTType tokens tau
441
441
| TType_ fun( d, r, n) ->
442
- accumulateTType d acc
443
- accumulateTType r acc
444
- acc ( Nullness( toNullnessToken n))
442
+ accumulateTType tokens d
443
+ accumulateTType tokens r
444
+ tokens.Add ( TypeToken. Nullness( toNullnessToken n))
445
445
| TType_ var( r, n) ->
446
- acc ( Stamp r.Stamp)
447
- acc ( Nullness( toNullnessToken n))
448
- | TType_ measure m -> accumulateMeasure m acc
446
+ tokens.Add( TypeToken.Stamp r.Stamp)
447
+ tokens.Add( TypeToken.Nullness( toNullnessToken n))
448
+ | TType_ measure m ->
449
+ accumulateMeasure tokens m
449
450
451
+ /// Get the full structure of a type as a sequence of tokens, suitable for equality
450
452
let getTypeStructure ty =
451
- let tokens = ResizeArray( )
452
- accumulateTType ty tokens.Add
453
+ let tokens = ResizeArray< TypeToken >( initialTokenCapacity )
454
+ accumulateTType tokens ty
453
455
tokens.ToArray()
0 commit comments