Reset type resolution stack when starting to compute variance (#53549)

This commit is contained in:
Gabriela Araujo Britto 2023-04-11 18:05:31 -03:00 committed by GitHub
parent 23469e9cb3
commit 2db688e36f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 233 additions and 57 deletions

View File

@ -2157,6 +2157,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
var resolutionTargets: TypeSystemEntity[] = [];
var resolutionResults: boolean[] = [];
var resolutionPropertyNames: TypeSystemPropertyName[] = [];
var resolutionStart = 0;
var inVarianceComputation = false;
var suggestionCount = 0;
var maximumSuggestionCount = 10;
@ -10106,7 +10108,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
function findResolutionCycleStartIndex(target: TypeSystemEntity, propertyName: TypeSystemPropertyName): number {
for (let i = resolutionTargets.length - 1; i >= 0; i--) {
for (let i = resolutionTargets.length - 1; i >= resolutionStart; i--) {
if (resolutionTargetHasProperty(resolutionTargets[i], resolutionPropertyNames[i])) {
return -1;
}
@ -22689,6 +22691,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const links = getSymbolLinks(symbol);
if (!links.variances) {
tracing?.push(tracing.Phase.CheckTypes, "getVariancesWorker", { arity: typeParameters.length, id: getTypeId(getDeclaredTypeOfSymbol(symbol)) });
const oldVarianceComputation = inVarianceComputation;
if (!inVarianceComputation) {
inVarianceComputation = true;
resolutionStart = resolutionTargets.length;
}
links.variances = emptyArray;
const variances = [];
for (const tp of typeParameters) {
@ -22727,6 +22734,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
variances.push(variance);
}
if (!oldVarianceComputation) {
inVarianceComputation = false;
resolutionStart = 0;
}
links.variances = variances;
tracing?.pop({ variances: variances.map(Debug.formatVariance) });
}

View File

@ -1,15 +0,0 @@
tests/cases/compiler/classVarianceResolveCircularity.ts(5,5): error TS7022: 'Value' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
==== tests/cases/compiler/classVarianceResolveCircularity.ts (1 errors) ====
// Issue #52813
class Bar<T> {
num!: number; // Swap to remove error
Value = callme(this).num;
~~~~~
!!! error TS7022: 'Value' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
Field: number = callme(this).num;
}
declare function callme(x: Bar<any>): Bar<any>;
declare function callme(x: object): string;

View File

@ -1,34 +0,0 @@
=== tests/cases/compiler/classVarianceResolveCircularity.ts ===
// Issue #52813
class Bar<T> {
>Bar : Symbol(Bar, Decl(classVarianceResolveCircularity.ts, 0, 0))
>T : Symbol(T, Decl(classVarianceResolveCircularity.ts, 2, 10))
num!: number; // Swap to remove error
>num : Symbol(Bar.num, Decl(classVarianceResolveCircularity.ts, 2, 14))
Value = callme(this).num;
>Value : Symbol(Bar.Value, Decl(classVarianceResolveCircularity.ts, 3, 17))
>callme(this).num : Symbol(Bar.num, Decl(classVarianceResolveCircularity.ts, 2, 14))
>callme : Symbol(callme, Decl(classVarianceResolveCircularity.ts, 6, 1), Decl(classVarianceResolveCircularity.ts, 7, 47))
>this : Symbol(Bar, Decl(classVarianceResolveCircularity.ts, 0, 0))
>num : Symbol(Bar.num, Decl(classVarianceResolveCircularity.ts, 2, 14))
Field: number = callme(this).num;
>Field : Symbol(Bar.Field, Decl(classVarianceResolveCircularity.ts, 4, 29))
>callme(this).num : Symbol(Bar.num, Decl(classVarianceResolveCircularity.ts, 2, 14))
>callme : Symbol(callme, Decl(classVarianceResolveCircularity.ts, 6, 1), Decl(classVarianceResolveCircularity.ts, 7, 47))
>this : Symbol(Bar, Decl(classVarianceResolveCircularity.ts, 0, 0))
>num : Symbol(Bar.num, Decl(classVarianceResolveCircularity.ts, 2, 14))
}
declare function callme(x: Bar<any>): Bar<any>;
>callme : Symbol(callme, Decl(classVarianceResolveCircularity.ts, 6, 1), Decl(classVarianceResolveCircularity.ts, 7, 47))
>x : Symbol(x, Decl(classVarianceResolveCircularity.ts, 7, 24))
>Bar : Symbol(Bar, Decl(classVarianceResolveCircularity.ts, 0, 0))
>Bar : Symbol(Bar, Decl(classVarianceResolveCircularity.ts, 0, 0))
declare function callme(x: object): string;
>callme : Symbol(callme, Decl(classVarianceResolveCircularity.ts, 6, 1), Decl(classVarianceResolveCircularity.ts, 7, 47))
>x : Symbol(x, Decl(classVarianceResolveCircularity.ts, 8, 24))

View File

@ -1,15 +1,15 @@
//// [classVarianceResolveCircularity.ts]
//// [classVarianceResolveCircularity1.ts]
// Issue #52813
class Bar<T> {
num!: number; // Swap to remove error
num!: number;
Value = callme(this).num;
Field: number = callme(this).num;
}
declare function callme(x: Bar<any>): Bar<any>;
declare function callme(x: object): string;
//// [classVarianceResolveCircularity.js]
//// [classVarianceResolveCircularity1.js]
"use strict";
// Issue #52813
var Bar = /** @class */ (function () {

View File

@ -0,0 +1,34 @@
=== tests/cases/compiler/classVarianceResolveCircularity1.ts ===
// Issue #52813
class Bar<T> {
>Bar : Symbol(Bar, Decl(classVarianceResolveCircularity1.ts, 0, 0))
>T : Symbol(T, Decl(classVarianceResolveCircularity1.ts, 2, 10))
num!: number;
>num : Symbol(Bar.num, Decl(classVarianceResolveCircularity1.ts, 2, 14))
Value = callme(this).num;
>Value : Symbol(Bar.Value, Decl(classVarianceResolveCircularity1.ts, 3, 17))
>callme(this).num : Symbol(Bar.num, Decl(classVarianceResolveCircularity1.ts, 2, 14))
>callme : Symbol(callme, Decl(classVarianceResolveCircularity1.ts, 6, 1), Decl(classVarianceResolveCircularity1.ts, 7, 47))
>this : Symbol(Bar, Decl(classVarianceResolveCircularity1.ts, 0, 0))
>num : Symbol(Bar.num, Decl(classVarianceResolveCircularity1.ts, 2, 14))
Field: number = callme(this).num;
>Field : Symbol(Bar.Field, Decl(classVarianceResolveCircularity1.ts, 4, 29))
>callme(this).num : Symbol(Bar.num, Decl(classVarianceResolveCircularity1.ts, 2, 14))
>callme : Symbol(callme, Decl(classVarianceResolveCircularity1.ts, 6, 1), Decl(classVarianceResolveCircularity1.ts, 7, 47))
>this : Symbol(Bar, Decl(classVarianceResolveCircularity1.ts, 0, 0))
>num : Symbol(Bar.num, Decl(classVarianceResolveCircularity1.ts, 2, 14))
}
declare function callme(x: Bar<any>): Bar<any>;
>callme : Symbol(callme, Decl(classVarianceResolveCircularity1.ts, 6, 1), Decl(classVarianceResolveCircularity1.ts, 7, 47))
>x : Symbol(x, Decl(classVarianceResolveCircularity1.ts, 7, 24))
>Bar : Symbol(Bar, Decl(classVarianceResolveCircularity1.ts, 0, 0))
>Bar : Symbol(Bar, Decl(classVarianceResolveCircularity1.ts, 0, 0))
declare function callme(x: object): string;
>callme : Symbol(callme, Decl(classVarianceResolveCircularity1.ts, 6, 1), Decl(classVarianceResolveCircularity1.ts, 7, 47))
>x : Symbol(x, Decl(classVarianceResolveCircularity1.ts, 8, 24))

View File

@ -1,14 +1,14 @@
=== tests/cases/compiler/classVarianceResolveCircularity.ts ===
=== tests/cases/compiler/classVarianceResolveCircularity1.ts ===
// Issue #52813
class Bar<T> {
>Bar : Bar<T>
num!: number; // Swap to remove error
num!: number;
>num : number
Value = callme(this).num;
>Value : any
>Value : number
>callme(this).num : number
>callme(this) : Bar<any>
>callme : { (x: Bar<any>): Bar<any>; (x: object): string; }

View File

@ -0,0 +1,37 @@
//// [classVarianceResolveCircularity2.ts]
// Issue #52813
export {};
class Bar<T> {
num!: number;
Value = callme(new Foo(this)).bar.num;
Field: number = callme(new Foo(this)).bar.num;
}
declare function callme(x: Foo<any>): Foo<any>;
declare function callme(x: object): string;
class Foo<T> {
bar!: Bar<T>;
constructor(bar: Bar<T>) {
this.bar = bar;
}
}
//// [classVarianceResolveCircularity2.js]
"use strict";
// Issue #52813
Object.defineProperty(exports, "__esModule", { value: true });
var Bar = /** @class */ (function () {
function Bar() {
this.Value = callme(new Foo(this)).bar.num;
this.Field = callme(new Foo(this)).bar.num;
}
return Bar;
}());
var Foo = /** @class */ (function () {
function Foo(bar) {
this.bar = bar;
}
return Foo;
}());

View File

@ -0,0 +1,63 @@
=== tests/cases/compiler/classVarianceResolveCircularity2.ts ===
// Issue #52813
export {};
class Bar<T> {
>Bar : Symbol(Bar, Decl(classVarianceResolveCircularity2.ts, 2, 10))
>T : Symbol(T, Decl(classVarianceResolveCircularity2.ts, 4, 10))
num!: number;
>num : Symbol(Bar.num, Decl(classVarianceResolveCircularity2.ts, 4, 14))
Value = callme(new Foo(this)).bar.num;
>Value : Symbol(Bar.Value, Decl(classVarianceResolveCircularity2.ts, 5, 17))
>callme(new Foo(this)).bar.num : Symbol(Bar.num, Decl(classVarianceResolveCircularity2.ts, 4, 14))
>callme(new Foo(this)).bar : Symbol(Foo.bar, Decl(classVarianceResolveCircularity2.ts, 12, 14))
>callme : Symbol(callme, Decl(classVarianceResolveCircularity2.ts, 8, 1), Decl(classVarianceResolveCircularity2.ts, 9, 47))
>Foo : Symbol(Foo, Decl(classVarianceResolveCircularity2.ts, 10, 43))
>this : Symbol(Bar, Decl(classVarianceResolveCircularity2.ts, 2, 10))
>bar : Symbol(Foo.bar, Decl(classVarianceResolveCircularity2.ts, 12, 14))
>num : Symbol(Bar.num, Decl(classVarianceResolveCircularity2.ts, 4, 14))
Field: number = callme(new Foo(this)).bar.num;
>Field : Symbol(Bar.Field, Decl(classVarianceResolveCircularity2.ts, 6, 42))
>callme(new Foo(this)).bar.num : Symbol(Bar.num, Decl(classVarianceResolveCircularity2.ts, 4, 14))
>callme(new Foo(this)).bar : Symbol(Foo.bar, Decl(classVarianceResolveCircularity2.ts, 12, 14))
>callme : Symbol(callme, Decl(classVarianceResolveCircularity2.ts, 8, 1), Decl(classVarianceResolveCircularity2.ts, 9, 47))
>Foo : Symbol(Foo, Decl(classVarianceResolveCircularity2.ts, 10, 43))
>this : Symbol(Bar, Decl(classVarianceResolveCircularity2.ts, 2, 10))
>bar : Symbol(Foo.bar, Decl(classVarianceResolveCircularity2.ts, 12, 14))
>num : Symbol(Bar.num, Decl(classVarianceResolveCircularity2.ts, 4, 14))
}
declare function callme(x: Foo<any>): Foo<any>;
>callme : Symbol(callme, Decl(classVarianceResolveCircularity2.ts, 8, 1), Decl(classVarianceResolveCircularity2.ts, 9, 47))
>x : Symbol(x, Decl(classVarianceResolveCircularity2.ts, 9, 24))
>Foo : Symbol(Foo, Decl(classVarianceResolveCircularity2.ts, 10, 43))
>Foo : Symbol(Foo, Decl(classVarianceResolveCircularity2.ts, 10, 43))
declare function callme(x: object): string;
>callme : Symbol(callme, Decl(classVarianceResolveCircularity2.ts, 8, 1), Decl(classVarianceResolveCircularity2.ts, 9, 47))
>x : Symbol(x, Decl(classVarianceResolveCircularity2.ts, 10, 24))
class Foo<T> {
>Foo : Symbol(Foo, Decl(classVarianceResolveCircularity2.ts, 10, 43))
>T : Symbol(T, Decl(classVarianceResolveCircularity2.ts, 12, 10))
bar!: Bar<T>;
>bar : Symbol(Foo.bar, Decl(classVarianceResolveCircularity2.ts, 12, 14))
>Bar : Symbol(Bar, Decl(classVarianceResolveCircularity2.ts, 2, 10))
>T : Symbol(T, Decl(classVarianceResolveCircularity2.ts, 12, 10))
constructor(bar: Bar<T>) {
>bar : Symbol(bar, Decl(classVarianceResolveCircularity2.ts, 14, 16))
>Bar : Symbol(Bar, Decl(classVarianceResolveCircularity2.ts, 2, 10))
>T : Symbol(T, Decl(classVarianceResolveCircularity2.ts, 12, 10))
this.bar = bar;
>this.bar : Symbol(Foo.bar, Decl(classVarianceResolveCircularity2.ts, 12, 14))
>this : Symbol(Foo, Decl(classVarianceResolveCircularity2.ts, 10, 43))
>bar : Symbol(Foo.bar, Decl(classVarianceResolveCircularity2.ts, 12, 14))
>bar : Symbol(bar, Decl(classVarianceResolveCircularity2.ts, 14, 16))
}
}

View File

@ -0,0 +1,60 @@
=== tests/cases/compiler/classVarianceResolveCircularity2.ts ===
// Issue #52813
export {};
class Bar<T> {
>Bar : Bar<T>
num!: number;
>num : number
Value = callme(new Foo(this)).bar.num;
>Value : number
>callme(new Foo(this)).bar.num : number
>callme(new Foo(this)).bar : Bar<any>
>callme(new Foo(this)) : Foo<any>
>callme : { (x: Foo<any>): Foo<any>; (x: object): string; }
>new Foo(this) : Foo<T>
>Foo : typeof Foo
>this : this
>bar : Bar<any>
>num : number
Field: number = callme(new Foo(this)).bar.num;
>Field : number
>callme(new Foo(this)).bar.num : number
>callme(new Foo(this)).bar : Bar<any>
>callme(new Foo(this)) : Foo<any>
>callme : { (x: Foo<any>): Foo<any>; (x: object): string; }
>new Foo(this) : Foo<T>
>Foo : typeof Foo
>this : this
>bar : Bar<any>
>num : number
}
declare function callme(x: Foo<any>): Foo<any>;
>callme : { (x: Foo<any>): Foo<any>; (x: object): string; }
>x : Foo<any>
declare function callme(x: object): string;
>callme : { (x: Foo<any>): Foo<any>; (x: object): string; }
>x : object
class Foo<T> {
>Foo : Foo<T>
bar!: Bar<T>;
>bar : Bar<T>
constructor(bar: Bar<T>) {
>bar : Bar<T>
this.bar = bar;
>this.bar = bar : Bar<T>
>this.bar : Bar<T>
>this : this
>bar : Bar<T>
>bar : Bar<T>
}
}

View File

@ -3,7 +3,7 @@
// Issue #52813
class Bar<T> {
num!: number; // Swap to remove error
num!: number;
Value = callme(this).num;
Field: number = callme(this).num;
}

View File

@ -0,0 +1,20 @@
// @strict: true
// Issue #52813
export {};
class Bar<T> {
num!: number;
Value = callme(new Foo(this)).bar.num;
Field: number = callme(new Foo(this)).bar.num;
}
declare function callme(x: Foo<any>): Foo<any>;
declare function callme(x: object): string;
class Foo<T> {
bar!: Bar<T>;
constructor(bar: Bar<T>) {
this.bar = bar;
}
}