Skip to content

Commit 4842501

Browse files
author
Arthur Ozga
committed
Move assignability test outside inner loop
1 parent dc85415 commit 4842501

File tree

1 file changed

+29
-13
lines changed

1 file changed

+29
-13
lines changed

src/compiler/checker.ts

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4766,9 +4766,37 @@ namespace ts {
47664766
outer: for (let t of targetSignatures) {
47674767
if (!t.hasStringLiterals || target.flags & TypeFlags.FromSignature) {
47684768
let localErrors = reportErrors;
4769+
let checkedAbstractAssignability = false;
47694770
for (let s of sourceSignatures) {
47704771
if (!s.hasStringLiterals || source.flags & TypeFlags.FromSignature) {
4771-
let related = signatureRelatedTo(s, t, localErrors);
4772+
let related = Ternary.True;
4773+
4774+
// Because the "abstractness" of a class is the same across all construct signatures
4775+
// (internally we are checking the corresponding declaration), it is enough to perform
4776+
// the check and report an error once over all pairs of source and target construct signatures.
4777+
if (!checkedAbstractAssignability) {
4778+
checkedAbstractAssignability = true;
4779+
4780+
let sourceErasedSignature = getErasedSignature(s);
4781+
let targetErasedSignature = getErasedSignature(t);
4782+
4783+
let sourceReturnType = sourceErasedSignature && getReturnTypeOfSignature(sourceErasedSignature);
4784+
let targetReturnType = targetErasedSignature && getReturnTypeOfSignature(targetErasedSignature);
4785+
4786+
let sourceReturnDecl = sourceReturnType && sourceReturnType.symbol && getDeclarationOfKind(sourceReturnType.symbol, SyntaxKind.ClassDeclaration);
4787+
let targetReturnDecl = targetReturnType && targetReturnType.symbol && getDeclarationOfKind(targetReturnType.symbol, SyntaxKind.ClassDeclaration);
4788+
let sourceIsAbstract = sourceReturnDecl && sourceReturnDecl.flags & NodeFlags.Abstract;
4789+
let targetIsAbstract = targetReturnDecl && targetReturnDecl.flags & NodeFlags.Abstract;
4790+
4791+
if (sourceIsAbstract && !targetIsAbstract) {
4792+
if (reportErrors) {
4793+
reportError(Diagnostics.Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type);
4794+
}
4795+
related = Ternary.False;
4796+
}
4797+
}
4798+
4799+
related &= signatureRelatedTo(s, t, localErrors);
47724800
if (related) {
47734801
result &= related;
47744802
errorInfo = saveErrorInfo;
@@ -4876,18 +4904,6 @@ namespace ts {
48764904
if (targetReturnType === voidType) return result;
48774905
let sourceReturnType = getReturnTypeOfSignature(source);
48784906

4879-
let sourceReturnDecl = sourceReturnType.symbol && getDeclarationOfKind(sourceReturnType.symbol, SyntaxKind.ClassDeclaration);
4880-
let targetReturnDecl = targetReturnType.symbol && getDeclarationOfKind(targetReturnType.symbol, SyntaxKind.ClassDeclaration);
4881-
let sourceIsAbstract = sourceReturnDecl && sourceReturnDecl.flags & NodeFlags.Abstract;
4882-
let targetIsAbstract = targetReturnDecl && targetReturnDecl.flags & NodeFlags.Abstract;
4883-
4884-
if (sourceIsAbstract && !targetIsAbstract) {
4885-
if (reportErrors) {
4886-
reportError(Diagnostics.Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type);
4887-
}
4888-
return Ternary.False;
4889-
}
4890-
48914907
return result & isRelatedTo(sourceReturnType, targetReturnType, reportErrors);
48924908
}
48934909

0 commit comments

Comments
 (0)