@@ -262,6 +262,7 @@ type InferenceContext struct {
262
262
mapper *TypeMapper // Mapper that fixes inferences
263
263
nonFixingMapper *TypeMapper // Mapper that doesn't fix inferences
264
264
returnMapper *TypeMapper // Type mapper for inferences from return types (if any)
265
+ outerReturnMapper *TypeMapper // Type mapper for inferences from return types of outer function (if any)
265
266
inferredTypeParameters []*Type // Inferred type parameters for function result
266
267
intraExpressionInferenceSites []IntraExpressionInferenceSite
267
268
}
@@ -7298,15 +7299,15 @@ func (c *Checker) instantiateTypeWithSingleGenericCallSignature(node *ast.Node,
7298
7299
if !hasOverlappingInferences(context.inferences, inferences) {
7299
7300
c.mergeInferences(context.inferences, inferences)
7300
7301
context.inferredTypeParameters = core.Concatenate(context.inferredTypeParameters, uniqueTypeParameters)
7301
- return c.getOrCreateTypeFromSignature(instantiatedSignature, nil )
7302
+ return c.getOrCreateTypeFromSignature(instantiatedSignature)
7302
7303
}
7303
7304
}
7304
7305
}
7305
7306
// TODO: The signature may reference any outer inference contexts, but we map pop off and then apply new inference contexts,
7306
7307
// and thus get different inferred types. That this is cached on the *first* such attempt is not currently an issue, since expression
7307
7308
// types *also* get cached on the first pass. If we ever properly speculate, though, the cached "isolatedSignatureType" signature
7308
7309
// field absolutely needs to be included in the list of speculative caches.
7309
- return c.getOrCreateTypeFromSignature(c.instantiateSignatureInContextOf(signature, contextualSignature, context, nil), c.getOuterInferenceTypeParameters() )
7310
+ return c.getOrCreateTypeFromSignature(c.instantiateSignatureInContextOf(signature, contextualSignature, context, nil))
7310
7311
}
7311
7312
7312
7313
func (c *Checker) getOuterInferenceTypeParameters() []*Type {
@@ -9164,7 +9165,7 @@ func (c *Checker) inferTypeArguments(node *ast.Node, signature *Signature, args
9164
9165
contextualSignature := c.getSingleCallSignature(instantiatedType)
9165
9166
var inferenceSourceType *Type
9166
9167
if contextualSignature != nil && len(contextualSignature.typeParameters) != 0 {
9167
- inferenceSourceType = c.getOrCreateTypeFromSignature(c.getSignatureInstantiationWithoutFillingInTypeArguments(contextualSignature, contextualSignature.typeParameters), nil )
9168
+ inferenceSourceType = c.getOrCreateTypeFromSignature(c.getSignatureInstantiationWithoutFillingInTypeArguments(contextualSignature, contextualSignature.typeParameters))
9168
9169
} else {
9169
9170
inferenceSourceType = instantiatedType
9170
9171
}
@@ -9175,10 +9176,14 @@ func (c *Checker) inferTypeArguments(node *ast.Node, signature *Signature, args
9175
9176
// from the return type. We need a separate inference pass here because (a) instantiation of
9176
9177
// the source type uses the outer context's return mapper (which excludes inferences made from
9177
9178
// outer arguments), and (b) we don't want any further inferences going into this context.
9179
+ // We use `createOuterReturnMapper` to ensure that all occurrences of outer type parameters are
9180
+ // replaced with inferences produced from the outer return type or preceding outer arguments.
9181
+ // This protects against circular inferences, i.e. avoiding situations where inferences reference
9182
+ // type parameters for which the inferences are being made.
9178
9183
returnContext := c.newInferenceContext(signature.typeParameters, signature, context.flags, nil)
9179
9184
var outerReturnMapper *TypeMapper
9180
9185
if outerContext != nil {
9181
- outerReturnMapper = outerContext.returnMapper
9186
+ outerReturnMapper = c.createOuterReturnMapper(outerContext)
9182
9187
}
9183
9188
returnSourceType := c.instantiateType(contextualType, outerReturnMapper)
9184
9189
c.inferTypes(returnContext.inferences, returnSourceType, inferenceTargetType, InferencePriorityNone, false)
@@ -16316,6 +16321,9 @@ func (c *Checker) getConstraintOfType(t *Type) *Type {
16316
16321
}
16317
16322
16318
16323
func (c *Checker) getConstraintOfTypeParameter(typeParameter *Type) *Type {
16324
+ if typeParameter.flags&TypeFlagsTypeParameter == 0 {
16325
+ return nil
16326
+ }
16319
16327
if c.hasNonCircularBaseConstraint(typeParameter) {
16320
16328
return c.getConstraintFromTypeParameter(typeParameter)
16321
16329
}
@@ -18447,8 +18455,10 @@ func (c *Checker) getSignatureInstantiation(sig *Signature, typeArguments []*Typ
18447
18455
if returnSignature != nil {
18448
18456
newReturnSignature := c.cloneSignature(returnSignature)
18449
18457
newReturnSignature.typeParameters = inferredTypeParameters
18458
+ newReturnType := c.getOrCreateTypeFromSignature(newReturnSignature)
18459
+ newReturnType.AsObjectType().mapper = instantiatedSignature.mapper
18450
18460
newInstantiatedSignature := c.cloneSignature(instantiatedSignature)
18451
- newInstantiatedSignature.resolvedReturnType = c.getOrCreateTypeFromSignature(newReturnSignature, nil)
18461
+ newInstantiatedSignature.resolvedReturnType = newReturnType
18452
18462
return newInstantiatedSignature
18453
18463
}
18454
18464
}
@@ -18513,7 +18523,7 @@ func (c *Checker) getSingleSignature(t *Type, kind SignatureKind, allowMembers b
18513
18523
return nil
18514
18524
}
18515
18525
18516
- func (c *Checker) getOrCreateTypeFromSignature(sig *Signature, outerTypeParameters []*Type ) *Type {
18526
+ func (c *Checker) getOrCreateTypeFromSignature(sig *Signature) *Type {
18517
18527
// There are two ways to declare a construct signature, one is by declaring a class constructor
18518
18528
// using the constructor keyword, and the other is declaring a bare construct signature in an
18519
18529
// object type literal or interface (using the new keyword). Each way of declaring a constructor
@@ -18525,17 +18535,12 @@ func (c *Checker) getOrCreateTypeFromSignature(sig *Signature, outerTypeParamete
18525
18535
}
18526
18536
// If declaration is undefined, it is likely to be the signature of the default constructor.
18527
18537
isConstructor := kind == ast.KindUnknown || kind == ast.KindConstructor || kind == ast.KindConstructSignature || kind == ast.KindConstructorType
18528
- // The type must have a symbol with a `Function` flag and a declaration in order to be correctly flagged as possibly containing
18529
- // type variables by `couldContainTypeVariables`
18530
- t := c.newObjectType(ObjectFlagsAnonymous|ObjectFlagsSingleSignatureType, c.newSymbol(ast.SymbolFlagsFunction, ast.InternalSymbolNameFunction))
18531
- if sig.declaration != nil && !ast.NodeIsSynthesized(sig.declaration) {
18532
- t.symbol.Declarations = []*ast.Node{sig.declaration}
18533
- t.symbol.ValueDeclaration = sig.declaration
18534
- }
18535
- if outerTypeParameters == nil && sig.declaration != nil {
18536
- outerTypeParameters = c.getOuterTypeParameters(sig.declaration, true /*includeThisTypes*/)
18538
+
18539
+ var symbol *ast.Symbol
18540
+ if sig.declaration != nil {
18541
+ symbol = sig.declaration.Symbol()
18537
18542
}
18538
- t.AsSingleSignatureType().outerTypeParameters = outerTypeParameters
18543
+ t := c.newObjectType(ObjectFlagsAnonymous|ObjectFlagsSingleSignatureType, symbol)
18539
18544
if isConstructor {
18540
18545
c.setStructuredTypeMembers(t, nil, nil, []*Signature{sig}, nil)
18541
18546
} else {
@@ -21182,6 +21187,9 @@ func (c *Checker) getDefaultTypeArgumentType(isInJavaScriptFile bool) *Type {
21182
21187
// this gets the instantiated default type of its target. If the type parameter has no default type or
21183
21188
// the default is circular, `undefined` is returned.
21184
21189
func (c *Checker) getDefaultFromTypeParameter(t *Type) *Type {
21190
+ if t.flags&TypeFlagsTypeParameter == 0 {
21191
+ return nil
21192
+ }
21185
21193
defaultType := c.getResolvedTypeParameterDefault(t)
21186
21194
if defaultType != c.noConstraintType && defaultType != c.circularConstraintType {
21187
21195
return defaultType
@@ -21349,7 +21357,6 @@ func (c *Checker) couldContainTypeVariablesWorker(t *Type) bool {
21349
21357
}
21350
21358
result := t.flags&TypeFlagsInstantiable != 0 ||
21351
21359
t.flags&TypeFlagsObject != 0 && !c.isNonGenericTopLevelType(t) && (objectFlags&ObjectFlagsReference != 0 && (t.AsTypeReference().node != nil || core.Some(c.getTypeArguments(t), c.couldContainTypeVariables)) ||
21352
- objectFlags&ObjectFlagsSingleSignatureType != 0 && len(t.AsSingleSignatureType().outerTypeParameters) != 0 ||
21353
21360
objectFlags&ObjectFlagsAnonymous != 0 && t.symbol != nil && t.symbol.Flags&(ast.SymbolFlagsFunction|ast.SymbolFlagsMethod|ast.SymbolFlagsClass|ast.SymbolFlagsTypeLiteral|ast.SymbolFlagsObjectLiteral) != 0 && t.symbol.Declarations != nil ||
21354
21361
objectFlags&(ObjectFlagsMapped|ObjectFlagsReverseMapped|ObjectFlagsObjectRestType|ObjectFlagsInstantiationExpressionType) != 0) ||
21355
21362
t.flags&TypeFlagsUnionOrIntersection != 0 && t.flags&TypeFlagsEnumLiteral == 0 && !c.isNonGenericTopLevelType(t) && core.Some(t.Types(), c.couldContainTypeVariables)
@@ -21458,9 +21465,9 @@ func (c *Checker) instantiateTypeWorker(t *Type, m *TypeMapper, alias *TypeAlias
21458
21465
// Handles instantiation of the following object types:
21459
21466
// AnonymousType (ObjectFlagsAnonymous)
21460
21467
// TypeReference with node != nil (ObjectFlagsReference)
21461
- // SingleSignatureType (ObjectFlagsSingleSignatureType)
21462
21468
// InstantiationExpressionType (ObjectFlagsInstantiationExpressionType)
21463
21469
// MappedType (ObjectFlagsMapped)
21470
+ // Note: ObjectFlagsSingleSignatureType types are handled as anonymous types
21464
21471
func (c *Checker) getObjectTypeInstantiation(t *Type, m *TypeMapper, alias *TypeAlias) *Type {
21465
21472
var declaration *ast.Node
21466
21473
var target *Type
@@ -21482,34 +21489,30 @@ func (c *Checker) getObjectTypeInstantiation(t *Type, m *TypeMapper, alias *Type
21482
21489
default:
21483
21490
target = t
21484
21491
}
21485
- if t.objectFlags&ObjectFlagsSingleSignatureType != 0 {
21486
- typeParameters = t.AsSingleSignatureType().outerTypeParameters
21487
- } else {
21488
- typeParameters = links.outerTypeParameters
21489
- if typeParameters == nil {
21490
- // The first time an anonymous type is instantiated we compute and store a list of the type
21491
- // parameters that are in scope (and therefore potentially referenced). For type literals that
21492
- // aren't the right hand side of a generic type alias declaration we optimize by reducing the
21493
- // set of type parameters to those that are possibly referenced in the literal.
21494
- typeParameters = c.getOuterTypeParameters(declaration, true /*includeThisTypes*/)
21495
- if len(target.alias.TypeArguments()) == 0 {
21496
- if t.objectFlags&(ObjectFlagsReference|ObjectFlagsInstantiationExpressionType) != 0 {
21497
- typeParameters = core.Filter(typeParameters, func(tp *Type) bool {
21498
- return c.isTypeParameterPossiblyReferenced(tp, declaration)
21499
- })
21500
- } else if target.symbol.Flags&(ast.SymbolFlagsMethod|ast.SymbolFlagsTypeLiteral) != 0 {
21501
- typeParameters = core.Filter(typeParameters, func(tp *Type) bool {
21502
- return core.Some(t.symbol.Declarations, func(d *ast.Node) bool {
21503
- return c.isTypeParameterPossiblyReferenced(tp, d)
21504
- })
21492
+ typeParameters = links.outerTypeParameters
21493
+ if typeParameters == nil {
21494
+ // The first time an anonymous type is instantiated we compute and store a list of the type
21495
+ // parameters that are in scope (and therefore potentially referenced). For type literals that
21496
+ // aren't the right hand side of a generic type alias declaration we optimize by reducing the
21497
+ // set of type parameters to those that are possibly referenced in the literal.
21498
+ typeParameters = c.getOuterTypeParameters(declaration, true /*includeThisTypes*/)
21499
+ if len(target.alias.TypeArguments()) == 0 {
21500
+ if t.objectFlags&(ObjectFlagsReference|ObjectFlagsInstantiationExpressionType) != 0 {
21501
+ typeParameters = core.Filter(typeParameters, func(tp *Type) bool {
21502
+ return c.isTypeParameterPossiblyReferenced(tp, declaration)
21503
+ })
21504
+ } else if target.symbol.Flags&(ast.SymbolFlagsMethod|ast.SymbolFlagsTypeLiteral) != 0 {
21505
+ typeParameters = core.Filter(typeParameters, func(tp *Type) bool {
21506
+ return core.Some(t.symbol.Declarations, func(d *ast.Node) bool {
21507
+ return c.isTypeParameterPossiblyReferenced(tp, d)
21505
21508
})
21506
- }
21507
- }
21508
- if typeParameters == nil {
21509
- typeParameters = []*Type{}
21509
+ })
21510
21510
}
21511
- links.outerTypeParameters = typeParameters
21512
21511
}
21512
+ if typeParameters == nil {
21513
+ typeParameters = []*Type{}
21514
+ }
21515
+ links.outerTypeParameters = typeParameters
21513
21516
}
21514
21517
if len(typeParameters) == 0 {
21515
21518
return t
@@ -21534,12 +21537,10 @@ func (c *Checker) getObjectTypeInstantiation(t *Type, m *TypeMapper, alias *Type
21534
21537
}
21535
21538
result := data.instantiations[key]
21536
21539
if result == nil {
21537
- if t.objectFlags&ObjectFlagsSingleSignatureType != 0 {
21538
- result = c.instantiateAnonymousType(t, m, nil /*alias*/)
21539
- data.instantiations[key] = result
21540
- return result
21541
- }
21542
21540
newMapper := newTypeMapper(typeParameters, typeArguments)
21541
+ if target.objectFlags&ObjectFlagsSingleSignatureType != 0 && m != nil {
21542
+ newMapper = c.combineTypeMappers(newMapper, m)
21543
+ }
21543
21544
switch {
21544
21545
case target.objectFlags&ObjectFlagsReference != 0:
21545
21546
result = c.createDeferredTypeReference(t.Target(), t.AsTypeReference().node, newMapper, newAlias)
@@ -21635,8 +21636,6 @@ func (c *Checker) instantiateAnonymousType(t *Type, m *TypeMapper, alias *TypeAl
21635
21636
freshTypeParameter.AsTypeParameter().mapper = m
21636
21637
case t.objectFlags&ObjectFlagsInstantiationExpressionType != 0:
21637
21638
result.AsInstantiationExpressionType().node = t.AsInstantiationExpressionType().node
21638
- case t.objectFlags&ObjectFlagsSingleSignatureType != 0:
21639
- result.AsSingleSignatureType().outerTypeParameters = t.AsSingleSignatureType().outerTypeParameters
21640
21639
}
21641
21640
if alias == nil {
21642
21641
alias = c.instantiateTypeAlias(t.alias, m)
@@ -24161,7 +24160,7 @@ func (c *Checker) newObjectType(objectFlags ObjectFlags, symbol *ast.Symbol) *Ty
24161
24160
case objectFlags&ObjectFlagsInstantiationExpressionType != 0:
24162
24161
data = &InstantiationExpressionType{}
24163
24162
case objectFlags&ObjectFlagsSingleSignatureType != 0:
24164
- data = &SingleSignatureType {}
24163
+ data = &ObjectType {}
24165
24164
case objectFlags&ObjectFlagsAnonymous != 0:
24166
24165
data = &ObjectType{}
24167
24166
default:
@@ -28447,7 +28446,7 @@ func (c *Checker) getContextualTypeForArgumentAtIndex(callTarget *ast.Node, argI
28447
28446
func (c *Checker) getContextualTypeForDecorator(decorator *ast.Node) *Type {
28448
28447
signature := c.getDecoratorCallSignature(decorator)
28449
28448
if signature != nil {
28450
- return c.getOrCreateTypeFromSignature(signature, nil )
28449
+ return c.getOrCreateTypeFromSignature(signature)
28451
28450
}
28452
28451
return nil
28453
28452
}
@@ -28977,7 +28976,7 @@ func (c *Checker) getESDecoratorCallSignature(decorator *ast.Node) *Signature {
28977
28976
// instance, depending on whether the member was `static`.
28978
28977
var valueType *Type
28979
28978
if ast.IsMethodDeclaration(node) {
28980
- valueType = c.getOrCreateTypeFromSignature(c.getSignatureFromDeclaration(node), nil )
28979
+ valueType = c.getOrCreateTypeFromSignature(c.getSignatureFromDeclaration(node))
28981
28980
} else {
28982
28981
valueType = c.getTypeOfNode(node)
28983
28982
}
@@ -29144,7 +29143,7 @@ func (c *Checker) newESDecoratorCallSignature(targetType *Type, contextType *Typ
29144
29143
// Creates a synthetic `FunctionType`
29145
29144
func (c *Checker) newFunctionType(typeParameters []*Type, thisParameter *ast.Symbol, parameters []*ast.Symbol, returnType *Type) *Type {
29146
29145
signature := c.newCallSignature(typeParameters, thisParameter, parameters, returnType)
29147
- return c.getOrCreateTypeFromSignature(signature, nil )
29146
+ return c.getOrCreateTypeFromSignature(signature)
29148
29147
}
29149
29148
29150
29149
func (c *Checker) newGetterFunctionType(t *Type) *Type {
0 commit comments