@@ -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
}
@@ -7307,15 +7308,15 @@ func (c *Checker) instantiateTypeWithSingleGenericCallSignature(node *ast.Node,
7307
7308
if !hasOverlappingInferences(context.inferences, inferences) {
7308
7309
c.mergeInferences(context.inferences, inferences)
7309
7310
context.inferredTypeParameters = core.Concatenate(context.inferredTypeParameters, uniqueTypeParameters)
7310
- return c.getOrCreateTypeFromSignature(instantiatedSignature, nil )
7311
+ return c.getOrCreateTypeFromSignature(instantiatedSignature)
7311
7312
}
7312
7313
}
7313
7314
}
7314
7315
// TODO: The signature may reference any outer inference contexts, but we map pop off and then apply new inference contexts,
7315
7316
// and thus get different inferred types. That this is cached on the *first* such attempt is not currently an issue, since expression
7316
7317
// types *also* get cached on the first pass. If we ever properly speculate, though, the cached "isolatedSignatureType" signature
7317
7318
// field absolutely needs to be included in the list of speculative caches.
7318
- return c.getOrCreateTypeFromSignature(c.instantiateSignatureInContextOf(signature, contextualSignature, context, nil), c.getOuterInferenceTypeParameters() )
7319
+ return c.getOrCreateTypeFromSignature(c.instantiateSignatureInContextOf(signature, contextualSignature, context, nil))
7319
7320
}
7320
7321
7321
7322
func (c *Checker) getOuterInferenceTypeParameters() []*Type {
@@ -9173,7 +9174,7 @@ func (c *Checker) inferTypeArguments(node *ast.Node, signature *Signature, args
9173
9174
contextualSignature := c.getSingleCallSignature(instantiatedType)
9174
9175
var inferenceSourceType *Type
9175
9176
if contextualSignature != nil && len(contextualSignature.typeParameters) != 0 {
9176
- inferenceSourceType = c.getOrCreateTypeFromSignature(c.getSignatureInstantiationWithoutFillingInTypeArguments(contextualSignature, contextualSignature.typeParameters), nil )
9177
+ inferenceSourceType = c.getOrCreateTypeFromSignature(c.getSignatureInstantiationWithoutFillingInTypeArguments(contextualSignature, contextualSignature.typeParameters))
9177
9178
} else {
9178
9179
inferenceSourceType = instantiatedType
9179
9180
}
@@ -9184,10 +9185,14 @@ func (c *Checker) inferTypeArguments(node *ast.Node, signature *Signature, args
9184
9185
// from the return type. We need a separate inference pass here because (a) instantiation of
9185
9186
// the source type uses the outer context's return mapper (which excludes inferences made from
9186
9187
// outer arguments), and (b) we don't want any further inferences going into this context.
9188
+ // We use `createOuterReturnMapper` to ensure that all occurrences of outer type parameters are
9189
+ // replaced with inferences produced from the outer return type or preceding outer arguments.
9190
+ // This protects against circular inferences, i.e. avoiding situations where inferences reference
9191
+ // type parameters for which the inferences are being made.
9187
9192
returnContext := c.newInferenceContext(signature.typeParameters, signature, context.flags, nil)
9188
9193
var outerReturnMapper *TypeMapper
9189
9194
if outerContext != nil {
9190
- outerReturnMapper = outerContext.returnMapper
9195
+ outerReturnMapper = c.createOuterReturnMapper(outerContext)
9191
9196
}
9192
9197
returnSourceType := c.instantiateType(contextualType, outerReturnMapper)
9193
9198
c.inferTypes(returnContext.inferences, returnSourceType, inferenceTargetType, InferencePriorityNone, false)
@@ -16426,6 +16431,10 @@ func (c *Checker) hasNonCircularBaseConstraint(t *Type) bool {
16426
16431
16427
16432
// This is a worker function. Use getConstraintOfTypeParameter which guards against circular constraints
16428
16433
func (c *Checker) getConstraintFromTypeParameter(t *Type) *Type {
16434
+ if t.flags&TypeFlagsTypeParameter == 0 {
16435
+ return nil
16436
+ }
16437
+
16429
16438
tp := t.AsTypeParameter()
16430
16439
if tp.constraint == nil {
16431
16440
var constraint *Type
@@ -18545,8 +18554,10 @@ func (c *Checker) getSignatureInstantiation(sig *Signature, typeArguments []*Typ
18545
18554
if returnSignature != nil {
18546
18555
newReturnSignature := c.cloneSignature(returnSignature)
18547
18556
newReturnSignature.typeParameters = inferredTypeParameters
18557
+ newReturnType := c.getOrCreateTypeFromSignature(newReturnSignature)
18558
+ newReturnType.AsObjectType().mapper = instantiatedSignature.mapper
18548
18559
newInstantiatedSignature := c.cloneSignature(instantiatedSignature)
18549
- newInstantiatedSignature.resolvedReturnType = c.getOrCreateTypeFromSignature(newReturnSignature, nil)
18560
+ newInstantiatedSignature.resolvedReturnType = newReturnType
18550
18561
return newInstantiatedSignature
18551
18562
}
18552
18563
}
@@ -18611,7 +18622,7 @@ func (c *Checker) getSingleSignature(t *Type, kind SignatureKind, allowMembers b
18611
18622
return nil
18612
18623
}
18613
18624
18614
- func (c *Checker) getOrCreateTypeFromSignature(sig *Signature, outerTypeParameters []*Type ) *Type {
18625
+ func (c *Checker) getOrCreateTypeFromSignature(sig *Signature) *Type {
18615
18626
// There are two ways to declare a construct signature, one is by declaring a class constructor
18616
18627
// using the constructor keyword, and the other is declaring a bare construct signature in an
18617
18628
// object type literal or interface (using the new keyword). Each way of declaring a constructor
@@ -18623,17 +18634,12 @@ func (c *Checker) getOrCreateTypeFromSignature(sig *Signature, outerTypeParamete
18623
18634
}
18624
18635
// If declaration is undefined, it is likely to be the signature of the default constructor.
18625
18636
isConstructor := kind == ast.KindUnknown || kind == ast.KindConstructor || kind == ast.KindConstructSignature || kind == ast.KindConstructorType
18626
- // The type must have a symbol with a `Function` flag and a declaration in order to be correctly flagged as possibly containing
18627
- // type variables by `couldContainTypeVariables`
18628
- t := c.newObjectType(ObjectFlagsAnonymous|ObjectFlagsSingleSignatureType, c.newSymbol(ast.SymbolFlagsFunction, ast.InternalSymbolNameFunction))
18629
- if sig.declaration != nil && !ast.NodeIsSynthesized(sig.declaration) {
18630
- t.symbol.Declarations = []*ast.Node{sig.declaration}
18631
- t.symbol.ValueDeclaration = sig.declaration
18632
- }
18633
- if outerTypeParameters == nil && sig.declaration != nil {
18634
- outerTypeParameters = c.getOuterTypeParameters(sig.declaration, true /*includeThisTypes*/)
18637
+
18638
+ var symbol *ast.Symbol
18639
+ if sig.declaration != nil {
18640
+ symbol = sig.declaration.Symbol()
18635
18641
}
18636
- t.AsSingleSignatureType().outerTypeParameters = outerTypeParameters
18642
+ t := c.newObjectType(ObjectFlagsAnonymous|ObjectFlagsSingleSignatureType, symbol)
18637
18643
if isConstructor {
18638
18644
c.setStructuredTypeMembers(t, nil, nil, []*Signature{sig}, nil)
18639
18645
} else {
@@ -21290,6 +21296,9 @@ func (c *Checker) getDefaultTypeArgumentType(isInJavaScriptFile bool) *Type {
21290
21296
// this gets the instantiated default type of its target. If the type parameter has no default type or
21291
21297
// the default is circular, `undefined` is returned.
21292
21298
func (c *Checker) getDefaultFromTypeParameter(t *Type) *Type {
21299
+ if t.flags&TypeFlagsTypeParameter == 0 {
21300
+ return nil
21301
+ }
21293
21302
defaultType := c.getResolvedTypeParameterDefault(t)
21294
21303
if defaultType != c.noConstraintType && defaultType != c.circularConstraintType {
21295
21304
return defaultType
@@ -21457,7 +21466,6 @@ func (c *Checker) couldContainTypeVariablesWorker(t *Type) bool {
21457
21466
}
21458
21467
result := t.flags&TypeFlagsInstantiable != 0 ||
21459
21468
t.flags&TypeFlagsObject != 0 && !c.isNonGenericTopLevelType(t) && (objectFlags&ObjectFlagsReference != 0 && (t.AsTypeReference().node != nil || core.Some(c.getTypeArguments(t), c.couldContainTypeVariables)) ||
21460
- objectFlags&ObjectFlagsSingleSignatureType != 0 && len(t.AsSingleSignatureType().outerTypeParameters) != 0 ||
21461
21469
objectFlags&ObjectFlagsAnonymous != 0 && t.symbol != nil && t.symbol.Flags&(ast.SymbolFlagsFunction|ast.SymbolFlagsMethod|ast.SymbolFlagsClass|ast.SymbolFlagsTypeLiteral|ast.SymbolFlagsObjectLiteral) != 0 && t.symbol.Declarations != nil ||
21462
21470
objectFlags&(ObjectFlagsMapped|ObjectFlagsReverseMapped|ObjectFlagsObjectRestType|ObjectFlagsInstantiationExpressionType) != 0) ||
21463
21471
t.flags&TypeFlagsUnionOrIntersection != 0 && t.flags&TypeFlagsEnumLiteral == 0 && !c.isNonGenericTopLevelType(t) && core.Some(t.Types(), c.couldContainTypeVariables)
@@ -21564,9 +21572,8 @@ func (c *Checker) instantiateTypeWorker(t *Type, m *TypeMapper, alias *TypeAlias
21564
21572
}
21565
21573
21566
21574
// Handles instantiation of the following object types:
21567
- // AnonymousType (ObjectFlagsAnonymous)
21575
+ // AnonymousType (ObjectFlagsAnonymous|ObjectFlagsSingleSignatureType )
21568
21576
// TypeReference with node != nil (ObjectFlagsReference)
21569
- // SingleSignatureType (ObjectFlagsSingleSignatureType)
21570
21577
// InstantiationExpressionType (ObjectFlagsInstantiationExpressionType)
21571
21578
// MappedType (ObjectFlagsMapped)
21572
21579
func (c *Checker) getObjectTypeInstantiation(t *Type, m *TypeMapper, alias *TypeAlias) *Type {
@@ -21590,34 +21597,30 @@ func (c *Checker) getObjectTypeInstantiation(t *Type, m *TypeMapper, alias *Type
21590
21597
default:
21591
21598
target = t
21592
21599
}
21593
- if t.objectFlags&ObjectFlagsSingleSignatureType != 0 {
21594
- typeParameters = t.AsSingleSignatureType().outerTypeParameters
21595
- } else {
21596
- typeParameters = links.outerTypeParameters
21597
- if typeParameters == nil {
21598
- // The first time an anonymous type is instantiated we compute and store a list of the type
21599
- // parameters that are in scope (and therefore potentially referenced). For type literals that
21600
- // aren't the right hand side of a generic type alias declaration we optimize by reducing the
21601
- // set of type parameters to those that are possibly referenced in the literal.
21602
- typeParameters = c.getOuterTypeParameters(declaration, true /*includeThisTypes*/)
21603
- if len(target.alias.TypeArguments()) == 0 {
21604
- if t.objectFlags&(ObjectFlagsReference|ObjectFlagsInstantiationExpressionType) != 0 {
21605
- typeParameters = core.Filter(typeParameters, func(tp *Type) bool {
21606
- return c.isTypeParameterPossiblyReferenced(tp, declaration)
21607
- })
21608
- } else if target.symbol.Flags&(ast.SymbolFlagsMethod|ast.SymbolFlagsTypeLiteral) != 0 {
21609
- typeParameters = core.Filter(typeParameters, func(tp *Type) bool {
21610
- return core.Some(t.symbol.Declarations, func(d *ast.Node) bool {
21611
- return c.isTypeParameterPossiblyReferenced(tp, d)
21612
- })
21600
+ typeParameters = links.outerTypeParameters
21601
+ if typeParameters == nil {
21602
+ // The first time an anonymous type is instantiated we compute and store a list of the type
21603
+ // parameters that are in scope (and therefore potentially referenced). For type literals that
21604
+ // aren't the right hand side of a generic type alias declaration we optimize by reducing the
21605
+ // set of type parameters to those that are possibly referenced in the literal.
21606
+ typeParameters = c.getOuterTypeParameters(declaration, true /*includeThisTypes*/)
21607
+ if len(target.alias.TypeArguments()) == 0 {
21608
+ if t.objectFlags&(ObjectFlagsReference|ObjectFlagsInstantiationExpressionType) != 0 {
21609
+ typeParameters = core.Filter(typeParameters, func(tp *Type) bool {
21610
+ return c.isTypeParameterPossiblyReferenced(tp, declaration)
21611
+ })
21612
+ } else if target.symbol.Flags&(ast.SymbolFlagsMethod|ast.SymbolFlagsTypeLiteral) != 0 {
21613
+ typeParameters = core.Filter(typeParameters, func(tp *Type) bool {
21614
+ return core.Some(t.symbol.Declarations, func(d *ast.Node) bool {
21615
+ return c.isTypeParameterPossiblyReferenced(tp, d)
21613
21616
})
21614
- }
21615
- }
21616
- if typeParameters == nil {
21617
- typeParameters = []*Type{}
21617
+ })
21618
21618
}
21619
- links.outerTypeParameters = typeParameters
21620
21619
}
21620
+ if typeParameters == nil {
21621
+ typeParameters = []*Type{}
21622
+ }
21623
+ links.outerTypeParameters = typeParameters
21621
21624
}
21622
21625
if len(typeParameters) == 0 {
21623
21626
return t
@@ -21642,12 +21645,10 @@ func (c *Checker) getObjectTypeInstantiation(t *Type, m *TypeMapper, alias *Type
21642
21645
}
21643
21646
result := data.instantiations[key]
21644
21647
if result == nil {
21645
- if t.objectFlags&ObjectFlagsSingleSignatureType != 0 {
21646
- result = c.instantiateAnonymousType(t, m, nil /*alias*/)
21647
- data.instantiations[key] = result
21648
- return result
21649
- }
21650
21648
newMapper := newTypeMapper(typeParameters, typeArguments)
21649
+ if target.objectFlags&ObjectFlagsSingleSignatureType != 0 && m != nil {
21650
+ newMapper = c.combineTypeMappers(newMapper, m)
21651
+ }
21651
21652
switch {
21652
21653
case target.objectFlags&ObjectFlagsReference != 0:
21653
21654
result = c.createDeferredTypeReference(t.Target(), t.AsTypeReference().node, newMapper, newAlias)
@@ -21743,8 +21744,6 @@ func (c *Checker) instantiateAnonymousType(t *Type, m *TypeMapper, alias *TypeAl
21743
21744
freshTypeParameter.AsTypeParameter().mapper = m
21744
21745
case t.objectFlags&ObjectFlagsInstantiationExpressionType != 0:
21745
21746
result.AsInstantiationExpressionType().node = t.AsInstantiationExpressionType().node
21746
- case t.objectFlags&ObjectFlagsSingleSignatureType != 0:
21747
- result.AsSingleSignatureType().outerTypeParameters = t.AsSingleSignatureType().outerTypeParameters
21748
21747
}
21749
21748
if alias == nil {
21750
21749
alias = c.instantiateTypeAlias(t.alias, m)
@@ -24270,8 +24269,6 @@ func (c *Checker) newObjectType(objectFlags ObjectFlags, symbol *ast.Symbol) *Ty
24270
24269
data = &EvolvingArrayType{}
24271
24270
case objectFlags&ObjectFlagsInstantiationExpressionType != 0:
24272
24271
data = &InstantiationExpressionType{}
24273
- case objectFlags&ObjectFlagsSingleSignatureType != 0:
24274
- data = &SingleSignatureType{}
24275
24272
case objectFlags&ObjectFlagsAnonymous != 0:
24276
24273
data = &ObjectType{}
24277
24274
default:
@@ -28557,7 +28554,7 @@ func (c *Checker) getContextualTypeForArgumentAtIndex(callTarget *ast.Node, argI
28557
28554
func (c *Checker) getContextualTypeForDecorator(decorator *ast.Node) *Type {
28558
28555
signature := c.getDecoratorCallSignature(decorator)
28559
28556
if signature != nil {
28560
- return c.getOrCreateTypeFromSignature(signature, nil )
28557
+ return c.getOrCreateTypeFromSignature(signature)
28561
28558
}
28562
28559
return nil
28563
28560
}
@@ -29087,7 +29084,7 @@ func (c *Checker) getESDecoratorCallSignature(decorator *ast.Node) *Signature {
29087
29084
// instance, depending on whether the member was `static`.
29088
29085
var valueType *Type
29089
29086
if ast.IsMethodDeclaration(node) {
29090
- valueType = c.getOrCreateTypeFromSignature(c.getSignatureFromDeclaration(node), nil )
29087
+ valueType = c.getOrCreateTypeFromSignature(c.getSignatureFromDeclaration(node))
29091
29088
} else {
29092
29089
valueType = c.getTypeOfNode(node)
29093
29090
}
@@ -29254,7 +29251,7 @@ func (c *Checker) newESDecoratorCallSignature(targetType *Type, contextType *Typ
29254
29251
// Creates a synthetic `FunctionType`
29255
29252
func (c *Checker) newFunctionType(typeParameters []*Type, thisParameter *ast.Symbol, parameters []*ast.Symbol, returnType *Type) *Type {
29256
29253
signature := c.newCallSignature(typeParameters, thisParameter, parameters, returnType)
29257
- return c.getOrCreateTypeFromSignature(signature, nil )
29254
+ return c.getOrCreateTypeFromSignature(signature)
29258
29255
}
29259
29256
29260
29257
func (c *Checker) newGetterFunctionType(t *Type) *Type {
0 commit comments