Skip to content

Commit 25357f8

Browse files
committed
TType_app only
1 parent 068b3b5 commit 25357f8

File tree

2 files changed

+79
-77
lines changed

2 files changed

+79
-77
lines changed

src/Compiler/Checking/TypeRelations.fs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ type CanCoerce =
2929
type TTypeCacheKey =
3030
| TTypeCacheKey of TypeStructure * TypeStructure * CanCoerce
3131
static member TryGetFromStrippedTypes(ty1, ty2, canCoerce) =
32-
let t1, t2 = getTypeStructure ty1, getTypeStructure ty2
33-
if t1.IsPossiblyInfinite || t2.IsPossiblyInfinite then
34-
ValueNone
35-
else
36-
ValueSome (TTypeCacheKey(t1, t2, canCoerce))
32+
let tryGetTypeStructure ty =
33+
match ty with
34+
| TType_app _ -> tryGetTypeStructureOfStrippedType ty
35+
| _ -> ValueNone
36+
37+
(tryGetTypeStructure ty1, tryGetTypeStructure ty2)
38+
||> ValueOption.map2(fun t1 t2 -> TTypeCacheKey(t1, t2, canCoerce))
3739

3840
let getTypeSubsumptionCache =
3941
let factory (g: TcGlobals) =
@@ -137,10 +139,6 @@ let rec TypeFeasiblySubsumesType ndeep (g: TcGlobals) (amap: ImportMap) m (ty1:
137139

138140
let checkSubsumes ty1 ty2 =
139141
match ty1, ty2 with
140-
| TType_measure _, TType_measure _
141-
| TType_var _, _ | _, TType_var _ ->
142-
true
143-
144142
| TType_app (tc1, l1, _), TType_app (tc2, l2, _) when tyconRefEq g tc1 tc2 ->
145143
List.lengthsEqAndForall2 (TypesFeasiblyEquiv ndeep g amap m) l1 l2
146144

@@ -160,13 +158,17 @@ let rec TypeFeasiblySubsumesType ndeep (g: TcGlobals) (amap: ImportMap) m (ty1:
160158
// See if any interface in type hierarchy of ty2 is a supertype of ty1
161159
List.exists (TypeFeasiblySubsumesType (ndeep + 1) g amap m ty1 NoCoerce) interfaces
162160

163-
if g.langVersion.SupportsFeature LanguageFeature.UseTypeSubsumptionCache then
161+
match ty1, ty2 with
162+
| TType_measure _, TType_measure _
163+
| TType_var _, _ | _, TType_var _ ->
164+
true
165+
166+
| _ when g.langVersion.SupportsFeature LanguageFeature.UseTypeSubsumptionCache ->
164167
match TTypeCacheKey.TryGetFromStrippedTypes(ty1, ty2, canCoerce) with
165168
| ValueSome key ->
166169
(getTypeSubsumptionCache g).GetOrAdd(key, fun _ -> checkSubsumes ty1 ty2)
167170
| _ -> checkSubsumes ty1 ty2
168-
else
169-
checkSubsumes ty1 ty2
171+
| _ -> checkSubsumes ty1 ty2
170172

171173
and TypeFeasiblySubsumesTypeWithSupertypeCheck g amap m ndeep ty1 ty2 =
172174
match GetSuperTypeOfType g amap m ty2 with

src/Compiler/Utilities/TypeHashing.fs

Lines changed: 65 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
module internal Internal.Utilities.TypeHashing
22

33
open Internal.Utilities.Rational
4-
open Internal.Utilities.Library
54
open FSharp.Compiler.AbstractIL.IL
65
open FSharp.Compiler.Syntax
76
open FSharp.Compiler.TcGlobals
87
open FSharp.Compiler.Text
98
open FSharp.Compiler.TypedTree
109
open FSharp.Compiler.TypedTreeBasics
1110
open FSharp.Compiler.TypedTreeOps
12-
open System.Collections.Immutable
1311

1412
type ObserverVisibility =
1513
| PublicOnly
@@ -126,7 +124,6 @@ module HashAccessibility =
126124
| _ -> true
127125

128126
module rec HashTypes =
129-
open Microsoft.FSharp.Core.LanguagePrimitives
130127

131128
/// Hash a reference to a type
132129
let hashTyconRef tcref = hashTyconRefImpl tcref
@@ -371,7 +368,7 @@ module HashTastMemberOrVals =
371368
/// * Uses per-compilation stamps (entities, typars, anon records, measures).
372369
/// * Emits shape for union cases (declaring type stamp + case name), tuple structness,
373370
/// function arrows, forall binders, nullness, measures, generic arguments.
374-
/// * Unknown/variable nullness => NeverEqual token to force inequality (avoid unsound hits).
371+
/// * Does not include type constraints.
375372
///
376373
/// Non-goals:
377374
/// * Cross-compilation stability.
@@ -385,117 +382,120 @@ module StructuralUtilities =
385382
| Stamp of stamp: Stamp
386383
| UCase of name: string
387384
| Nullness of nullness: NullnessInfo
385+
| NullnessUnsolved
388386
| TupInfo of b: bool
387+
| Forall of int
389388
| MeasureOne
390389
| MeasureRational of int * int
391-
| UnconstrainedVar
392-
| Unsolved
390+
| Unsolved of int
391+
| Rigid of int
393392

394-
type TypeStructure =
395-
| TypeStructure of TypeToken[]
396-
| UnsolvedTypeStructure of TypeToken[]
397-
| PossiblyInfinite
393+
type TypeStructure = TypeStructure of TypeToken[]
398394

399-
let inline toNullnessToken (n: Nullness) =
395+
type private EmitContext =
396+
{
397+
typarMap: System.Collections.Generic.Dictionary<Stamp, int>
398+
}
399+
400+
let inline emitNullness (n: Nullness) =
400401
match n.TryEvaluate() with
401402
| ValueSome k -> TypeToken.Nullness k
402-
| _ -> TypeToken.Unsolved
403+
| ValueNone -> TypeToken.NullnessUnsolved
403404

404-
let rec private accumulateMeasure (m: Measure) =
405+
let rec private emitMeasure (m: Measure) =
405406
seq {
406407
match m with
407408
| Measure.Var mv -> TypeToken.Stamp mv.Stamp
408409
| Measure.Const(tcref, _) -> TypeToken.Stamp tcref.Stamp
409410
| Measure.Prod(m1, m2, _) ->
410-
yield! accumulateMeasure m1
411-
yield! accumulateMeasure m2
412-
| Measure.Inv m1 -> yield! accumulateMeasure m1
411+
yield! emitMeasure m1
412+
yield! emitMeasure m2
413+
| Measure.Inv m1 -> yield! emitMeasure m1
413414
| Measure.One _ -> TypeToken.MeasureOne
414415
| Measure.RationalPower(m1, r) ->
415-
yield! accumulateMeasure m1
416+
yield! emitMeasure m1
416417
TypeToken.MeasureRational(GetNumerator r, GetDenominator r)
417418
}
418419

419-
let rec private accumulateTypar (typar: Typar) =
420-
seq {
421-
match typar.Solution with
422-
| Some ty -> yield! accumulateTType ty
423-
| None ->
424-
if typar.Rigidity <> TyparRigidity.Rigid then
425-
TypeToken.Unsolved
426-
427-
// We don't emit details of the constraints, just the stamp to avoid collisions.
428-
if typar.Constraints.Length > 0 then
429-
TypeToken.Stamp typar.Stamp
430-
else
431-
TypeToken.UnconstrainedVar
432-
}
433-
434-
and private accumulateTType (ty: TType) =
420+
and private emitTType (env: EmitContext) (ty: TType) =
435421
seq {
436422
match ty with
437423
| TType_ucase(u, tinst) ->
438424
TypeToken.Stamp u.TyconRef.Stamp
439425
TypeToken.UCase u.CaseName
440426

441427
for arg in tinst do
442-
yield! accumulateTType arg
428+
yield! emitTType env arg
443429

444430
| TType_app(tcref, tinst, n) ->
445431
TypeToken.Stamp tcref.Stamp
446-
toNullnessToken n
432+
emitNullness n
447433

448434
for arg in tinst do
449-
yield! accumulateTType arg
435+
yield! emitTType env arg
450436

451437
| TType_anon(info, tys) ->
452438
TypeToken.Stamp info.Stamp
453439

454440
for arg in tys do
455-
yield! accumulateTType arg
441+
yield! emitTType env arg
456442

457443
| TType_tuple(tupInfo, tys) ->
458444
TypeToken.TupInfo(evalTupInfoIsStruct tupInfo)
459445

460446
for arg in tys do
461-
yield! accumulateTType arg
447+
yield! emitTType env arg
462448

463449
| TType_forall(tps, tau) ->
464450
for tp in tps do
465-
yield! accumulateTypar tp
451+
env.typarMap.[tp.Stamp] <- env.typarMap.Count
466452

467-
yield! accumulateTType tau
453+
TypeToken.Forall tps.Length
454+
455+
yield! emitTType env tau
468456

469457
| TType_fun(d, r, n) ->
470-
yield! accumulateTType d
471-
yield! accumulateTType r
472-
toNullnessToken n
458+
yield! emitTType env d
459+
yield! emitTType env r
460+
emitNullness n
473461

474462
| TType_var(r, n) ->
475-
toNullnessToken n
476-
yield! accumulateTypar r
477-
478-
| TType_measure m -> yield! accumulateMeasure m
463+
emitNullness n
464+
465+
let typarId =
466+
match env.typarMap.TryGetValue r.Stamp with
467+
| true, idx -> idx
468+
| _ ->
469+
let idx = env.typarMap.Count
470+
env.typarMap.[r.Stamp] <- idx
471+
idx
472+
473+
match r.Solution with
474+
| Some ty ->
475+
yield! emitTType env ty
476+
| None ->
477+
if r.Rigidity = TyparRigidity.Rigid then
478+
TypeToken.Rigid typarId
479+
else
480+
TypeToken.Unsolved typarId
481+
| TType_measure m -> yield! emitMeasure m
479482
}
480483

481-
// If the sequence got too long, just drop it, we could be dealing with an infinite type.
482-
let private toTypeStructure (tokens: TypeToken seq) =
483-
let tokens = tokens |> Seq.truncate 256 |> Seq.toArray
484+
let tryGetTypeStructureOfStrippedType (ty: TType) =
485+
486+
let env =
487+
{
488+
typarMap = System.Collections.Generic.Dictionary<Stamp, int>()
489+
}
490+
491+
let tokens =
492+
emitTType env ty
493+
|> Seq.filter (fun t -> t <> TypeToken.Nullness NullnessInfo.WithoutNull)
494+
|> Seq.truncate 256
495+
|> Seq.toArray
484496

497+
// If the sequence got too long, just drop it, we could be dealing with an infinite type.
485498
if tokens.Length = 256 then
486-
PossiblyInfinite
487-
elif tokens |> Array.exists _.IsUnsolved then
488-
UnsolvedTypeStructure tokens
499+
ValueNone
489500
else
490-
TypeStructure tokens
491-
492-
/// Get the full structure of a type as a sequence of tokens, suitable for equality
493-
let getTypeStructure =
494-
let shouldCache =
495-
function
496-
| PossiblyInfinite
497-
| UnsolvedTypeStructure _ -> false
498-
| _ -> true
499-
500-
// Speed up repeated calls by memoizing results for types that yield a stable structure.
501-
Extras.WeakMap.cacheConditionally shouldCache (fun ty -> accumulateTType ty |> toTypeStructure)
501+
ValueSome(TypeStructure tokens)

0 commit comments

Comments
 (0)