diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b7281687ad710..612abd197517a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -34806,7 +34806,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (candidate.typeParameters) { // If we are *inside the body of candidate*, we need to create a clone of `candidate` with differing type parameter identities, // so our inference results for this call doesn't pollute expression types referencing the outer type parameter! - if (candidate.declaration && findAncestor(node, a => a === candidate.declaration)) { + const paramLocation = candidate.typeParameters[0].symbol.declarations?.[0]?.parent; + const candidateParameterContext = paramLocation || (candidate.declaration && isConstructorDeclaration(candidate.declaration) ? candidate.declaration.parent : candidate.declaration); + if (candidateParameterContext && findAncestor(node, a => a === candidateParameterContext)) { candidate = getImplementationSignature(candidate); } let typeArgumentTypes: readonly Type[] | undefined; diff --git a/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.js b/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.js new file mode 100644 index 0000000000000..e407a66f3f087 --- /dev/null +++ b/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.js @@ -0,0 +1,73 @@ +//// [tests/cases/compiler/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts] //// + +//// [inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts] +// simple example +export class Test { + constructor(public a: A, public b: B) { } + + test(c: C): Test { + return new Test(this.b, c); + } +} + +// complicated one +interface Supervisor { + zip(right: Supervisor): Supervisor<[T, A]>; +} + +export class Zip implements Supervisor { + constructor( + readonly left: Supervisor, + readonly right: Supervisor, + ) { } + + zip(right: Supervisor): Supervisor<[[T0, T1], A]> { + return new Zip(this, right); + } +} + +// indirect +type Assign = Omit & U; + +class Base { + constructor(public t: T) { } +} + +export class Foo extends Base { + update(): Foo> { + const v: Assign = Object.assign(this.t, { x: 1 }); + return new Foo(v); + } +} + +//// [inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.js] +// simple example +export class Test { + constructor(a, b) { + this.a = a; + this.b = b; + } + test(c) { + return new Test(this.b, c); + } +} +export class Zip { + constructor(left, right) { + this.left = left; + this.right = right; + } + zip(right) { + return new Zip(this, right); + } +} +class Base { + constructor(t) { + this.t = t; + } +} +export class Foo extends Base { + update() { + const v = Object.assign(this.t, { x: 1 }); + return new Foo(v); + } +} diff --git a/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.symbols b/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.symbols new file mode 100644 index 0000000000000..5eff036d33422 --- /dev/null +++ b/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.symbols @@ -0,0 +1,138 @@ +//// [tests/cases/compiler/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts] //// + +=== inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts === +// simple example +export class Test { +>Test : Symbol(Test, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 0, 0)) +>A : Symbol(A, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 1, 18)) +>B : Symbol(B, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 1, 20)) + + constructor(public a: A, public b: B) { } +>a : Symbol(Test.a, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 2, 16)) +>A : Symbol(A, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 1, 18)) +>b : Symbol(Test.b, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 2, 28)) +>B : Symbol(B, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 1, 20)) + + test(c: C): Test { +>test : Symbol(Test.test, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 2, 45)) +>C : Symbol(C, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 4, 9)) +>c : Symbol(c, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 4, 12)) +>C : Symbol(C, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 4, 9)) +>Test : Symbol(Test, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 0, 0)) +>B : Symbol(B, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 1, 20)) +>C : Symbol(C, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 4, 9)) + + return new Test(this.b, c); +>Test : Symbol(Test, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 0, 0)) +>this.b : Symbol(Test.b, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 2, 28)) +>this : Symbol(Test, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 0, 0)) +>b : Symbol(Test.b, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 2, 28)) +>c : Symbol(c, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 4, 12)) + } +} + +// complicated one +interface Supervisor { +>Supervisor : Symbol(Supervisor, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 7, 1)) +>T : Symbol(T, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 10, 21)) + + zip(right: Supervisor): Supervisor<[T, A]>; +>zip : Symbol(Supervisor.zip, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 10, 29)) +>A : Symbol(A, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 11, 8)) +>right : Symbol(right, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 11, 11)) +>Supervisor : Symbol(Supervisor, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 7, 1)) +>A : Symbol(A, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 11, 8)) +>Supervisor : Symbol(Supervisor, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 7, 1)) +>T : Symbol(T, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 10, 21)) +>A : Symbol(A, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 11, 8)) +} + +export class Zip implements Supervisor { +>Zip : Symbol(Zip, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 12, 1)) +>T0 : Symbol(T0, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 14, 17)) +>T1 : Symbol(T1, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 14, 24)) +>Supervisor : Symbol(Supervisor, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 7, 1)) +>T0 : Symbol(T0, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 14, 17)) +>T1 : Symbol(T1, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 14, 24)) + + constructor( + readonly left: Supervisor, +>left : Symbol(Zip.left, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 15, 16)) +>Supervisor : Symbol(Supervisor, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 7, 1)) +>T0 : Symbol(T0, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 14, 17)) + + readonly right: Supervisor, +>right : Symbol(Zip.right, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 16, 38)) +>Supervisor : Symbol(Supervisor, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 7, 1)) +>T1 : Symbol(T1, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 14, 24)) + + ) { } + + zip(right: Supervisor): Supervisor<[[T0, T1], A]> { +>zip : Symbol(Zip.zip, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 18, 9)) +>A : Symbol(A, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 20, 8)) +>right : Symbol(right, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 20, 11)) +>Supervisor : Symbol(Supervisor, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 7, 1)) +>A : Symbol(A, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 20, 8)) +>Supervisor : Symbol(Supervisor, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 7, 1)) +>T0 : Symbol(T0, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 14, 17)) +>T1 : Symbol(T1, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 14, 24)) +>A : Symbol(A, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 20, 8)) + + return new Zip(this, right); +>Zip : Symbol(Zip, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 12, 1)) +>this : Symbol(Zip, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 12, 1)) +>right : Symbol(right, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 20, 11)) + } +} + +// indirect +type Assign = Omit & U; +>Assign : Symbol(Assign, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 23, 1)) +>T : Symbol(T, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 26, 12)) +>U : Symbol(U, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 26, 14)) +>Omit : Symbol(Omit, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 26, 12)) +>U : Symbol(U, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 26, 14)) +>U : Symbol(U, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 26, 14)) + +class Base { +>Base : Symbol(Base, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 26, 41)) +>T : Symbol(T, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 28, 11)) + + constructor(public t: T) { } +>t : Symbol(Base.t, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 29, 16)) +>T : Symbol(T, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 28, 11)) +} + +export class Foo extends Base { +>Foo : Symbol(Foo, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 30, 1)) +>T : Symbol(T, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 32, 17)) +>Base : Symbol(Base, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 26, 41)) +>T : Symbol(T, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 32, 17)) + + update(): Foo> { +>update : Symbol(Foo.update, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 32, 37)) +>Foo : Symbol(Foo, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 30, 1)) +>Assign : Symbol(Assign, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 23, 1)) +>T : Symbol(T, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 32, 17)) +>x : Symbol(x, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 33, 29)) + + const v: Assign = Object.assign(this.t, { x: 1 }); +>v : Symbol(v, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 34, 13)) +>Assign : Symbol(Assign, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 23, 1)) +>T : Symbol(T, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 32, 17)) +>x : Symbol(x, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 34, 28)) +>Object.assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>this.t : Symbol(Base.t, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 29, 16)) +>this : Symbol(Foo, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 30, 1)) +>t : Symbol(Base.t, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 29, 16)) +>x : Symbol(x, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 34, 67)) + + return new Foo(v); +>Foo : Symbol(Foo, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 30, 1)) +>v : Symbol(v, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 34, 13)) + } +} diff --git a/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.types b/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.types new file mode 100644 index 0000000000000..fd159c4a51979 --- /dev/null +++ b/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.types @@ -0,0 +1,139 @@ +//// [tests/cases/compiler/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts] //// + +=== inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts === +// simple example +export class Test { +>Test : Test +> : ^^^^^^^^^^ + + constructor(public a: A, public b: B) { } +>a : A +> : ^ +>b : B +> : ^ + + test(c: C): Test { +>test : (c: C) => Test +> : ^ ^^ ^^ ^^^^^ +>c : C +> : ^ + + return new Test(this.b, c); +>new Test(this.b, c) : Test +> : ^^^^^^^^^^ +>Test : typeof Test +> : ^^^^^^^^^^^ +>this.b : B +> : ^ +>this : this +> : ^^^^ +>b : B +> : ^ +>c : C +> : ^ + } +} + +// complicated one +interface Supervisor { + zip(right: Supervisor): Supervisor<[T, A]>; +>zip : (right: Supervisor) => Supervisor<[T, A]> +> : ^ ^^ ^^ ^^^^^ +>right : Supervisor +> : ^^^^^^^^^^^^^ +} + +export class Zip implements Supervisor { +>Zip : Zip +> : ^^^^^^^^^^^ + + constructor( + readonly left: Supervisor, +>left : Supervisor +> : ^^^^^^^^^^^^^^ + + readonly right: Supervisor, +>right : Supervisor +> : ^^^^^^^^^^^^^^ + + ) { } + + zip(right: Supervisor): Supervisor<[[T0, T1], A]> { +>zip : (right: Supervisor) => Supervisor<[[T0, T1], A]> +> : ^ ^^ ^^ ^^^^^ +>right : Supervisor +> : ^^^^^^^^^^^^^ + + return new Zip(this, right); +>new Zip(this, right) : Zip<[T0, T1], A> +> : ^^^^^^^^^^^^^^^^ +>Zip : typeof Zip +> : ^^^^^^^^^^ +>this : this +> : ^^^^ +>right : Supervisor +> : ^^^^^^^^^^^^^ + } +} + +// indirect +type Assign = Omit & U; +>Assign : Assign +> : ^^^^^^^^^^^^ + +class Base { +>Base : Base +> : ^^^^^^^ + + constructor(public t: T) { } +>t : T +> : ^ +} + +export class Foo extends Base { +>Foo : Foo +> : ^^^^^^ +>Base : Base +> : ^^^^^^^ + + update(): Foo> { +>update : () => Foo> +> : ^^^^^^ +>x : number +> : ^^^^^^ + + const v: Assign = Object.assign(this.t, { x: 1 }); +>v : Assign +> : ^^^^^^^^^^^^^^^ ^^^^ +>x : number +> : ^^^^^^ +>Object.assign(this.t, { x: 1 }) : T & { x: number; } +> : ^^^^^^^^^^^^^^^^^^ +>Object.assign : { (target: T_1, source: U): T_1 & U; (target: T_2, source1: U_1, source2: V): T_2 & U_1 & V; (target: T_3, source1: U_2, source2: V_1, source3: W): T_3 & U_2 & V_1 & W; (target: object, ...sources: any[]): any; } +> : ^^^ ^^^^^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^ ^^ ^^^^^^^^^ +>Object : ObjectConstructor +> : ^^^^^^^^^^^^^^^^^ +>assign : { (target: T_1, source: U): T_1 & U; (target: T_2, source1: U_1, source2: V): T_2 & U_1 & V; (target: T_3, source1: U_2, source2: V_1, source3: W): T_3 & U_2 & V_1 & W; (target: object, ...sources: any[]): any; } +> : ^^^ ^^^^^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^ ^^ ^^^^^^^^^ +>this.t : T +> : ^ +>this : this +> : ^^^^ +>t : T +> : ^ +>{ x: 1 } : { x: number; } +> : ^^^^^^^^^^^^^^ +>x : number +> : ^^^^^^ +>1 : 1 +> : ^ + + return new Foo(v); +>new Foo(v) : Foo> +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>Foo : typeof Foo +> : ^^^^^^^^^^ +>v : Assign +> : ^^^^^^^^^^^^^^^^^^^^^^^^^ + } +} diff --git a/tests/cases/compiler/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts b/tests/cases/compiler/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts new file mode 100644 index 0000000000000..f35f4bf0d4610 --- /dev/null +++ b/tests/cases/compiler/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts @@ -0,0 +1,39 @@ +// @target: es6 +// simple example +export class Test { + constructor(public a: A, public b: B) { } + + test(c: C): Test { + return new Test(this.b, c); + } +} + +// complicated one +interface Supervisor { + zip(right: Supervisor): Supervisor<[T, A]>; +} + +export class Zip implements Supervisor { + constructor( + readonly left: Supervisor, + readonly right: Supervisor, + ) { } + + zip(right: Supervisor): Supervisor<[[T0, T1], A]> { + return new Zip(this, right); + } +} + +// indirect +type Assign = Omit & U; + +class Base { + constructor(public t: T) { } +} + +export class Foo extends Base { + update(): Foo> { + const v: Assign = Object.assign(this.t, { x: 1 }); + return new Foo(v); + } +} \ No newline at end of file