Skip to content

Commit 64474ae

Browse files
committed
Move cold value-symbol links out of the hot records
Most value symbols never need write types, computed names, or containing types. These three pointers nevertheless occupy every checker link record, which is the largest retained allocation on the VS Code workload. Allocate that metadata only when it is used, shrinking the hot record from 56 to 40 bytes without changing symbol identity or cache semantics. VS Code src, six samples versus compact inference mappers: │ before │ after │ │ retained-B │ retained-B vs base │ ExternalProgram-20 5.029Gi 4.874Gi -3.09% (p=0.002 n=6) │ before │ after │ │ scan-B │ scan-B vs base │ ExternalProgram-20 4.664Gi 4.508Gi -3.33% (p=0.002 n=6) │ before │ after │ │ B/op │ B/op vs base │ ExternalProgram-20 6.200Gi 6.043Gi -2.54% (p=0.002 n=6) Allocation count is unchanged. All 321 semantic diagnostics and all 10284 files are identical. CLI diagnostic text and compiler counts match exactly as well. No GC tuning is used.
1 parent 8f868f9 commit 64474ae

7 files changed

Lines changed: 137 additions & 49 deletions

File tree

‎tsc/internal/checker/checker.go‎

Lines changed: 39 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,7 @@ type Checker struct {
685685
indexedAccessTypeArena core.Arena[IndexedAccessType]
686686
conditionalTypeArena core.Arena[ConditionalType]
687687
typeListArena core.Arena[*Type]
688+
valueSymbolExtraArena core.Arena[valueSymbolExtra]
688689
freeTypeSets *temporaryTypeSet
689690
mergedSymbols map[*ast.Symbol]*ast.Symbol
690691
mergedExportsChecked collections.Set[*ast.Symbol]
@@ -12163,7 +12164,7 @@ func (c *Checker) forEachProperty(prop *ast.Symbol, callback func(p *ast.Symbol)
1216312164
if prop.CheckFlags()&ast.CheckFlagsSynthetic == 0 {
1216412165
return callback(prop)
1216512166
}
12166-
for _, t := range c.valueSymbolLinks.Get(prop).containingType.Types() {
12167+
for _, t := range c.valueSymbolLinks.Get(prop).getContainingType().Types() {
1216712168
p := c.getPropertyOfType(t, prop.Name())
1216812169
if p != nil && c.forEachProperty(p, callback) {
1216912170
return true
@@ -13505,7 +13506,7 @@ func (c *Checker) checkObjectLiteral(node *ast.Node, checkMode CheckMode) *Type
1350513506
}
1350613507
links := c.valueSymbolLinks.Get(prop)
1350713508
if nameType != nil {
13508-
links.nameType = nameType
13509+
links.setNameType(c, nameType)
1350913510
}
1351013511
if inDestructuringPattern && c.hasDefaultValue(memberDecl) {
1351113512
// If object literal is an assignment pattern and if the assignment pattern specifies a default value
@@ -13750,7 +13751,7 @@ func (c *Checker) getSpreadType(left *Type, right *Type, symbol *ast.Symbol, obj
1375013751
c.spreadLinks.Get(result).leftSpread = leftProp
1375113752
c.spreadLinks.Get(result).rightSpread = rightProp
1375213753
result.SetDeclarations(declarations)
13753-
links.nameType = c.valueSymbolLinks.Get(leftProp).nameType
13754+
links.setNameType(c, c.valueSymbolLinks.Get(leftProp).getNameType())
1375413755
members[leftProp.Name()] = result
1375513756
}
1375613757
} else {
@@ -13837,7 +13838,7 @@ func (c *Checker) tryMergeUnionOfObjectTypeAndEmptyObject(t *Type, readonly bool
1383713838
links.resolvedType = c.addOptionalityEx(c.getTypeOfSymbol(prop), true /*isProperty*/, true /*isOptional*/)
1383813839
}
1383913840
result.SetDeclarations(prop.Declarations())
13840-
links.nameType = c.valueSymbolLinks.Get(prop).nameType
13841+
links.setNameType(c, c.valueSymbolLinks.Get(prop).getNameType())
1384113842
c.mappedSymbolLinks.Get(result).syntheticOrigin = prop
1384213843
members[prop.Name()] = result
1384313844
}
@@ -13867,7 +13868,7 @@ func (c *Checker) getSpreadSymbol(prop *ast.Symbol, readonly bool) *ast.Symbol {
1386713868
links.resolvedType = c.getTypeOfSymbol(prop)
1386813869
}
1386913870
result.SetDeclarations(prop.Declarations())
13870-
links.nameType = c.valueSymbolLinks.Get(prop).nameType
13871+
links.setNameType(c, c.valueSymbolLinks.Get(prop).getNameType())
1387113872
c.mappedSymbolLinks.Get(result).syntheticOrigin = prop
1387213873
return result
1387313874
}
@@ -16136,7 +16137,7 @@ func (c *Checker) createDefaultPropertyWrapperForModule(symbol *ast.Symbol, orig
1613616137
memberTable := make(ast.SymbolTable)
1613716138
newSymbol := c.newSymbol(ast.SymbolFlagsAlias, ast.InternalSymbolNameDefault)
1613816139
newSymbol.SetParent(originalSymbol)
16139-
c.valueSymbolLinks.Get(newSymbol).nameType = c.getStringLiteralType("default")
16140+
c.valueSymbolLinks.Get(newSymbol).setNameType(c, c.getStringLiteralType("default"))
1614016141
c.aliasSymbolLinks.Get(newSymbol).aliasTarget = c.resolveSymbol(symbol)
1614116142
memberTable[ast.InternalSymbolNameDefault] = newSymbol
1614216143
if anonymousSymbol == nil && originalSymbol != nil {
@@ -16482,7 +16483,7 @@ func (c *Checker) lateBindMember(parent *ast.Symbol, earlySymbols ast.SymbolTabl
1648216483
}
1648316484
lateSymbol = c.newSymbolEx(ast.SymbolFlagsNone, memberName, ast.CheckFlagsLate)
1648416485
}
16485-
c.valueSymbolLinks.Get(lateSymbol).nameType = t
16486+
c.valueSymbolLinks.Get(lateSymbol).setNameType(c, t)
1648616487
c.addDeclarationToLateBoundSymbol(lateSymbol, decl, symbolFlags)
1648716488
if lateSymbol.Parent() == nil {
1648816489
lateSymbol.SetParent(parent)
@@ -16841,19 +16842,19 @@ func (c *Checker) getTypeOfSymbolWithDeferredType(symbol *ast.Symbol) *Type {
1684116842

1684216843
func (c *Checker) getWriteTypeOfSymbolWithDeferredType(symbol *ast.Symbol) *Type {
1684316844
links := c.valueSymbolLinks.Get(symbol)
16844-
if links.writeType == nil {
16845+
if links.getWriteType() == nil {
1684516846
deferred := c.deferredSymbolLinks.Get(symbol)
1684616847
if len(deferred.writeConstituents) != 0 {
1684716848
if deferred.parent.flags&TypeFlagsUnion != 0 {
16848-
links.writeType = c.getUnionType(deferred.writeConstituents)
16849+
links.setWriteType(c, c.getUnionType(deferred.writeConstituents))
1684916850
} else {
16850-
links.writeType = c.getIntersectionType(deferred.writeConstituents)
16851+
links.setWriteType(c, c.getIntersectionType(deferred.writeConstituents))
1685116852
}
1685216853
} else {
16853-
links.writeType = c.getTypeOfSymbolWithDeferredType(symbol)
16854+
links.setWriteType(c, c.getTypeOfSymbolWithDeferredType(symbol))
1685416855
}
1685516856
}
16856-
return links.writeType
16857+
return links.getWriteType()
1685716858
}
1685816859

1685916860
// Distinct write types come only from set accessors, but synthetic union and intersection
@@ -16865,7 +16866,7 @@ func (c *Checker) getWriteTypeOfSymbol(symbol *ast.Symbol) *Type {
1686516866
return c.getWriteTypeOfSymbolWithDeferredType(symbol)
1686616867
}
1686716868
links := c.valueSymbolLinks.Get(symbol)
16868-
return core.OrElse(links.writeType, links.resolvedType)
16869+
return core.OrElse(links.getWriteType(), links.resolvedType)
1686916870
}
1687016871
if symbol.Flags()&ast.SymbolFlagsProperty != 0 {
1687116872
return c.removeMissingType(c.getTypeOfSymbol(symbol), symbol.Flags()&ast.SymbolFlagsOptional != 0)
@@ -16963,10 +16964,10 @@ func (c *Checker) getTypeOfInstantiatedSymbol(symbol *ast.Symbol) *Type {
1696316964

1696416965
func (c *Checker) getWriteTypeOfInstantiatedSymbol(symbol *ast.Symbol) *Type {
1696516966
links := c.valueSymbolLinks.Get(symbol)
16966-
if links.writeType == nil {
16967-
links.writeType = c.instantiateType(c.getWriteTypeOfSymbol(links.target), links.mapper)
16967+
if links.getWriteType() == nil {
16968+
links.setWriteType(c, c.instantiateType(c.getWriteTypeOfSymbol(links.target), links.mapper))
1696816969
}
16969-
return links.writeType
16970+
return links.getWriteType()
1697016971
}
1697116972

1697216973
func (c *Checker) getTypeOfVariableOrParameterOrProperty(symbol *ast.Symbol) *Type {
@@ -19021,7 +19022,7 @@ func (c *Checker) getTypeOfAccessors(symbol *ast.Symbol) *Type {
1902119022

1902219023
func (c *Checker) getWriteTypeOfAccessors(symbol *ast.Symbol) *Type {
1902319024
links := c.valueSymbolLinks.Get(symbol)
19024-
if links.writeType == nil {
19025+
if links.getWriteType() == nil {
1902519026
if !c.pushTypeResolution(symbol, TypeSystemPropertyNameWriteType) {
1902619027
return c.errorType
1902719028
}
@@ -19040,15 +19041,15 @@ func (c *Checker) getWriteTypeOfAccessors(symbol *ast.Symbol) *Type {
1904019041
writeType = c.anyType
1904119042
}
1904219043
// Absent an explicit setter type annotation we use the read type of the accessor.
19043-
if links.writeType == nil {
19044+
if links.getWriteType() == nil {
1904419045
if writeType != nil {
19045-
links.writeType = writeType
19046+
links.setWriteType(c, writeType)
1904619047
} else {
19047-
links.writeType = c.getTypeOfAccessors(symbol)
19048+
links.setWriteType(c, c.getTypeOfAccessors(symbol))
1904819049
}
1904919050
}
1905019051
}
19051-
return links.writeType
19052+
return links.getWriteType()
1905219053
}
1905319054

1905419055
func (c *Checker) getTypeOfAlias(symbol *ast.Symbol) *Type {
@@ -19268,7 +19269,7 @@ func (c *Checker) typeResolutionHasProperty(r *TypeResolution) bool {
1926819269
case TypeSystemPropertyNameInitializerIsUndefined:
1926919270
return c.nodeLinks.Get(r.target.(*ast.Node)).flags&NodeCheckFlagsInitializerIsUndefinedComputed != 0
1927019271
case TypeSystemPropertyNameWriteType:
19271-
return c.valueSymbolLinks.Get(r.target.(*ast.Symbol)).writeType != nil
19272+
return c.valueSymbolLinks.Get(r.target.(*ast.Symbol)).getWriteType() != nil
1927219273
case TypeSystemPropertyNameAliasTarget:
1927319274
return c.aliasSymbolLinks.Get(r.target.(*ast.Symbol)).aliasTarget != nil
1927419275
}
@@ -21218,7 +21219,7 @@ func (c *Checker) instantiateSymbol(symbol *ast.Symbol, m *TypeMapper) *ast.Symb
2121821219
return symbol
2121921220
}
2122021221
// If we're a setter, check writeType.
21221-
if links.writeType != nil && !c.couldContainTypeVariables(links.writeType) {
21222+
if links.getWriteType() != nil && !c.couldContainTypeVariables(links.getWriteType()) {
2122221223
return symbol
2122321224
}
2122421225
}
@@ -21235,7 +21236,7 @@ func (c *Checker) instantiateSymbol(symbol *ast.Symbol, m *TypeMapper) *ast.Symb
2123521236
resultLinks := c.valueSymbolLinks.Get(result)
2123621237
resultLinks.target = symbol
2123721238
resultLinks.mapper = m
21238-
resultLinks.nameType = links.nameType
21239+
resultLinks.setNameType(c, links.getNameType())
2123921240
return result
2124021241
}
2124121242

@@ -21367,7 +21368,7 @@ func (c *Checker) resolveMappedTypeMembers(t *Type) {
2136721368
// property symbol's name type be the union of those enum member types.
2136821369
if existingProp := members[propName]; existingProp != nil {
2136921370
valueLinks := c.valueSymbolLinks.Get(existingProp)
21370-
valueLinks.nameType = c.getUnionType([]*Type{valueLinks.nameType, propNameType})
21371+
valueLinks.setNameType(c, c.getUnionType([]*Type{valueLinks.getNameType(), propNameType}))
2137121372
mappedLinks := c.mappedSymbolLinks.Get(existingProp)
2137221373
mappedLinks.keyType = c.getUnionType([]*Type{mappedLinks.keyType, keyType})
2137321374
} else {
@@ -21385,8 +21386,8 @@ func (c *Checker) resolveMappedTypeMembers(t *Type) {
2138521386
prop := c.newSymbol(ast.SymbolFlagsProperty|core.IfElse(isOptional, ast.SymbolFlagsOptional, 0), propName)
2138621387
prop.SetCheckFlags(lateFlag | ast.CheckFlagsMapped | core.IfElse(isReadonly, ast.CheckFlagsReadonly, 0) | core.IfElse(stripOptional, ast.CheckFlagsStripOptional, 0))
2138721388
valueLinks := c.valueSymbolLinks.Get(prop)
21388-
valueLinks.containingType = t
21389-
valueLinks.nameType = propNameType
21389+
valueLinks.setContainingType(c, t)
21390+
valueLinks.setNameType(c, propNameType)
2139021391
mappedLinks := c.mappedSymbolLinks.Get(prop)
2139121392
mappedLinks.keyType = keyType
2139221393
if modifiersProp != nil {
@@ -21433,7 +21434,7 @@ func (c *Checker) resolveMappedTypeMembers(t *Type) {
2143321434
func (c *Checker) getTypeOfMappedSymbol(symbol *ast.Symbol) *Type {
2143421435
links := c.valueSymbolLinks.Get(symbol)
2143521436
if links.resolvedType == nil {
21436-
mappedType := links.containingType
21437+
mappedType := links.getContainingType()
2143721438
if !c.pushTypeResolution(symbol, TypeSystemPropertyNameType) {
2143821439
mappedType.AsMappedType().containsError = true
2143921440
return c.errorType
@@ -22047,9 +22048,9 @@ func (c *Checker) createUnionOrIntersectionProperty(containingType *Type, name s
2204722048
clone.SetParent(singleProp.ValueDeclaration().Symbol().Parent())
2204822049
}
2204922050
links := c.valueSymbolLinks.Get(clone)
22050-
links.containingType = containingType
22051+
links.setContainingType(c, containingType)
2205122052
links.mapper = singlePropMapper
22052-
links.writeType = c.getWriteTypeOfSymbol(singleProp)
22053+
links.setWriteType(c, c.getWriteTypeOfSymbol(singleProp))
2205322054
return clone
2205422055
}
2205522056
if propSet.Size() == 0 {
@@ -22074,7 +22075,7 @@ func (c *Checker) createUnionOrIntersectionProperty(containingType *Type, name s
2207422075
t := c.getTypeOfSymbol(prop)
2207522076
if firstType == nil {
2207622077
firstType = t
22077-
nameType = c.valueSymbolLinks.Get(prop).nameType
22078+
nameType = c.valueSymbolLinks.Get(prop).getNameType()
2207822079
}
2207922080
writeType := c.getWriteTypeOfSymbol(prop)
2208022081
if writeTypes != nil || writeType != t {
@@ -22103,8 +22104,8 @@ func (c *Checker) createUnionOrIntersectionProperty(containingType *Type, name s
2210322104
result.SetParent(firstValueDeclaration.Symbol().Parent())
2210422105
}
2210522106
links := c.valueSymbolLinks.Get(result)
22106-
links.containingType = containingType
22107-
links.nameType = nameType
22107+
links.setContainingType(c, containingType)
22108+
links.setNameType(c, nameType)
2210822109
if len(propTypes) > 2 {
2210922110
// When `propTypes` has the potential to explode in size when normalized, defer normalization until absolutely needed
2211022111
result.SetCheckFlags(result.CheckFlags() | ast.CheckFlagsDeferredType)
@@ -22121,9 +22122,9 @@ func (c *Checker) createUnionOrIntersectionProperty(containingType *Type, name s
2212122122
}
2212222123
if writeTypes != nil {
2212322124
if isUnion {
22124-
links.writeType = c.getUnionType(writeTypes)
22125+
links.setWriteType(c, c.getUnionType(writeTypes))
2212522126
} else {
22126-
links.writeType = c.getIntersectionType(writeTypes)
22127+
links.setWriteType(c, c.getIntersectionType(writeTypes))
2212722128
}
2212822129
}
2212922130
return result
@@ -22178,7 +22179,7 @@ func (c *Checker) createSymbolWithType(source *ast.Symbol, t *Type) *ast.Symbol
2217822179
links := c.valueSymbolLinks.Get(symbol)
2217922180
links.resolvedType = t
2218022181
links.target = source
22181-
links.nameType = c.valueSymbolLinks.Get(source).nameType
22182+
links.setNameType(c, c.valueSymbolLinks.Get(source).getNameType())
2218222183
return symbol
2218322184
}
2218422185

@@ -27349,7 +27350,7 @@ func (c *Checker) getLiteralTypeFromProperties(t *Type, include TypeFlags, inclu
2734927350

2735027351
func (c *Checker) getLiteralTypeFromProperty(prop *ast.Symbol, include TypeFlags, includeNonPublic bool) *Type {
2735127352
if includeNonPublic || getDeclarationModifierFlagsFromSymbol(prop)&ast.ModifierFlagsNonPublicAccessibilityModifier == 0 {
27352-
t := c.valueSymbolLinks.Get(c.getLateBoundSymbol(prop)).nameType
27353+
t := c.valueSymbolLinks.Get(c.getLateBoundSymbol(prop)).getNameType()
2735327354
if t == nil {
2735427355
if prop.Name() == ast.InternalSymbolNameDefault {
2735527356
t = c.getStringLiteralType("default")
@@ -30572,7 +30573,7 @@ func (c *Checker) getContextualTypeForObjectLiteralElement(element *ast.Node, co
3057230573
// in the type. It will just be "__computed", which does not appear in any
3057330574
// SymbolTable.
3057430575
symbol := c.getSymbolOfDeclaration(element)
30575-
return c.getTypeOfPropertyOfContextualTypeEx(t, symbol.Name(), c.valueSymbolLinks.Get(symbol).nameType)
30576+
return c.getTypeOfPropertyOfContextualTypeEx(t, symbol.Name(), c.valueSymbolLinks.Get(symbol).getNameType())
3057630577
}
3057730578
if ast.HasDynamicName(element) {
3057830579
name := ast.GetNameOfDeclaration(element)

‎tsc/internal/checker/exports.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ func (c *Checker) GetUnionType(types []*Type) *Type {
8383

8484
func (c *Checker) GetNameTypeOfSymbol(symbol *ast.Symbol) *Type {
8585
if links := c.valueSymbolLinks.TryGet(symbol); links != nil {
86-
return links.nameType
86+
return links.getNameType()
8787
}
8888
return nil
8989
}

‎tsc/internal/checker/inference.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1132,7 +1132,7 @@ func (c *Checker) resolveReverseMappedTypeMembers(t *Type) {
11321132
checkFlags := ast.CheckFlagsReverseMapped | core.IfElse(readonlyMask && c.isReadonlySymbol(prop), ast.CheckFlagsReadonly, 0)
11331133
inferredProp := c.newSymbolEx(ast.SymbolFlagsProperty|prop.Flags()&optionalMask, prop.Name(), checkFlags)
11341134
inferredProp.SetDeclarations(prop.Declarations())
1135-
c.valueSymbolLinks.Get(inferredProp).nameType = c.valueSymbolLinks.Get(prop).nameType
1135+
c.valueSymbolLinks.Get(inferredProp).setNameType(c, c.valueSymbolLinks.Get(prop).getNameType())
11361136
links := c.ReverseMappedSymbolLinks.Get(inferredProp)
11371137
links.propertyType = c.getTypeOfSymbol(prop)
11381138
constraintTarget := r.constraintType.AsIndexType().target

‎tsc/internal/checker/nodebuilderimpl.go‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ func (b *NodeBuilderImpl) symbolToNode(symbol *ast.Symbol, meaning ast.SymbolFla
591591
}
592592
}
593593
if b.ch.valueSymbolLinks.Has(symbol) {
594-
nameType := b.ch.valueSymbolLinks.Get(symbol).nameType
594+
nameType := b.ch.valueSymbolLinks.Get(symbol).getNameType()
595595
if nameType != nil && nameType.flags&(TypeFlagsEnumLiteral|TypeFlagsUniqueESSymbol) != 0 {
596596
oldEnclosing := b.ctx.enclosingDeclaration
597597
b.ctx.enclosingDeclaration = nameType.symbol.ValueDeclaration()
@@ -936,7 +936,7 @@ func isDefaultBindingContext(location *ast.Node) bool {
936936

937937
func (b *NodeBuilderImpl) getNameOfSymbolFromNameType(symbol *ast.Symbol) string {
938938
if b.ch.valueSymbolLinks.Has(symbol) {
939-
nameType := b.ch.valueSymbolLinks.Get(symbol).nameType
939+
nameType := b.ch.valueSymbolLinks.Get(symbol).getNameType()
940940
if nameType == nil {
941941
return ""
942942
}
@@ -993,7 +993,7 @@ func (b *NodeBuilderImpl) getNameOfSymbolAsWritten(symbol *ast.Symbol) string {
993993
// return symbol.Name
994994
// }
995995
if ast.IsComputedPropertyName(name) && symbol.CheckFlags()&ast.CheckFlagsLate == 0 {
996-
if b.ch.valueSymbolLinks.Has(symbol) && b.ch.valueSymbolLinks.Get(symbol).nameType != nil && b.ch.valueSymbolLinks.Get(symbol).nameType.flags&TypeFlagsStringOrNumberLiteral != 0 {
996+
if b.ch.valueSymbolLinks.Has(symbol) && b.ch.valueSymbolLinks.Get(symbol).getNameType() != nil && b.ch.valueSymbolLinks.Get(symbol).getNameType().flags&TypeFlagsStringOrNumberLiteral != 0 {
997997
result := b.getNameOfSymbolFromNameType(symbol)
998998
if len(result) > 0 {
999999
return result
@@ -2544,7 +2544,7 @@ func (b *NodeBuilderImpl) getPropertyNameNodeForSymbolFromNameType(symbol *ast.S
25442544
if !b.ch.valueSymbolLinks.Has(symbol) {
25452545
return nil
25462546
}
2547-
nameType := b.ch.valueSymbolLinks.TryGet(symbol).nameType
2547+
nameType := b.ch.valueSymbolLinks.TryGet(symbol).getNameType()
25482548
if nameType == nil {
25492549
return nil
25502550
}

‎tsc/internal/checker/services.go‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -413,15 +413,15 @@ func (c *Checker) GetRootSymbols(symbol *ast.Symbol) []*ast.Symbol {
413413

414414
func (c *Checker) GetMappedTypeSymbolOfProperty(symbol *ast.Symbol) *ast.Symbol {
415415
if valueLinks := c.valueSymbolLinks.TryGet(symbol); valueLinks != nil {
416-
return valueLinks.containingType.symbol
416+
return valueLinks.getContainingType().symbol
417417
}
418418
return nil
419419
}
420420

421421
func (c *Checker) getImmediateRootSymbols(symbol *ast.Symbol) []*ast.Symbol {
422422
if symbol.CheckFlags()&ast.CheckFlagsSynthetic != 0 {
423423
return core.MapNonNil(
424-
c.valueSymbolLinks.Get(symbol).containingType.Types(),
424+
c.valueSymbolLinks.Get(symbol).getContainingType().Types(),
425425
func(t *Type) *ast.Symbol {
426426
return c.getPropertyOfType(t, symbol.Name())
427427
},

0 commit comments

Comments
 (0)