Skip to content

Commit

Permalink
Merge pull request #32362 from microsoft/fix32230
Browse files Browse the repository at this point in the history
Fix type parameter inference cache invalidation logic
  • Loading branch information
ahejlsberg authored Jul 12, 2019
2 parents 851156d + 4b9ca33 commit 303297a
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 4 deletions.
16 changes: 12 additions & 4 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15266,15 +15266,23 @@ namespace ts {
const inference = inferences[i];
if (t === inference.typeParameter) {
if (fix && !inference.isFixed) {
clearCachedInferences(inferences);
inference.isFixed = true;
inference.inferredType = undefined;
}
return getInferredType(context, i);
}
}
return t;
}

function clearCachedInferences(inferences: InferenceInfo[]) {
for (const inference of inferences) {
if (!inference.isFixed) {
inference.inferredType = undefined;
}
}
}

function createInferenceInfo(typeParameter: TypeParameter): InferenceInfo {
return {
typeParameter,
Expand Down Expand Up @@ -15554,17 +15562,17 @@ namespace ts {
if (contravariant && !bivariant) {
if (!contains(inference.contraCandidates, candidate)) {
inference.contraCandidates = append(inference.contraCandidates, candidate);
inference.inferredType = undefined;
clearCachedInferences(inferences);
}
}
else if (!contains(inference.candidates, candidate)) {
inference.candidates = append(inference.candidates, candidate);
inference.inferredType = undefined;
clearCachedInferences(inferences);
}
}
if (!(priority & InferencePriority.ReturnType) && target.flags & TypeFlags.TypeParameter && inference.topLevel && !isTypeParameterAtTopLevel(originalTarget, <TypeParameter>target)) {
inference.topLevel = false;
inference.inferredType = undefined;
clearCachedInferences(inferences);
}
}
return;
Expand Down
37 changes: 37 additions & 0 deletions tests/baselines/reference/typeInferenceCacheInvalidation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//// [typeInferenceCacheInvalidation.ts]
// Repro from #32230

type Callback<TFoo, TBar> = (foo: TFoo, bar: TBar) => any

declare function example<TFoo, TBar, TCallback extends Callback<TFoo, TBar>>(
foo: TFoo,
callback: TCallback,
bar: TBar,
): TCallback

example(42, (foo, bar) => ({
t: () => {
let s: string = bar;
}
}), '42');

example(42, (foo, bar) => ({
t() {
let s: string = bar;
}
}), '42');


//// [typeInferenceCacheInvalidation.js]
"use strict";
// Repro from #32230
example(42, function (foo, bar) { return ({
t: function () {
var s = bar;
}
}); }, '42');
example(42, function (foo, bar) { return ({
t: function () {
var s = bar;
}
}); }, '42');
64 changes: 64 additions & 0 deletions tests/baselines/reference/typeInferenceCacheInvalidation.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
=== tests/cases/compiler/typeInferenceCacheInvalidation.ts ===
// Repro from #32230

type Callback<TFoo, TBar> = (foo: TFoo, bar: TBar) => any
>Callback : Symbol(Callback, Decl(typeInferenceCacheInvalidation.ts, 0, 0))
>TFoo : Symbol(TFoo, Decl(typeInferenceCacheInvalidation.ts, 2, 14))
>TBar : Symbol(TBar, Decl(typeInferenceCacheInvalidation.ts, 2, 19))
>foo : Symbol(foo, Decl(typeInferenceCacheInvalidation.ts, 2, 29))
>TFoo : Symbol(TFoo, Decl(typeInferenceCacheInvalidation.ts, 2, 14))
>bar : Symbol(bar, Decl(typeInferenceCacheInvalidation.ts, 2, 39))
>TBar : Symbol(TBar, Decl(typeInferenceCacheInvalidation.ts, 2, 19))

declare function example<TFoo, TBar, TCallback extends Callback<TFoo, TBar>>(
>example : Symbol(example, Decl(typeInferenceCacheInvalidation.ts, 2, 57))
>TFoo : Symbol(TFoo, Decl(typeInferenceCacheInvalidation.ts, 4, 25))
>TBar : Symbol(TBar, Decl(typeInferenceCacheInvalidation.ts, 4, 30))
>TCallback : Symbol(TCallback, Decl(typeInferenceCacheInvalidation.ts, 4, 36))
>Callback : Symbol(Callback, Decl(typeInferenceCacheInvalidation.ts, 0, 0))
>TFoo : Symbol(TFoo, Decl(typeInferenceCacheInvalidation.ts, 4, 25))
>TBar : Symbol(TBar, Decl(typeInferenceCacheInvalidation.ts, 4, 30))

foo: TFoo,
>foo : Symbol(foo, Decl(typeInferenceCacheInvalidation.ts, 4, 77))
>TFoo : Symbol(TFoo, Decl(typeInferenceCacheInvalidation.ts, 4, 25))

callback: TCallback,
>callback : Symbol(callback, Decl(typeInferenceCacheInvalidation.ts, 5, 14))
>TCallback : Symbol(TCallback, Decl(typeInferenceCacheInvalidation.ts, 4, 36))

bar: TBar,
>bar : Symbol(bar, Decl(typeInferenceCacheInvalidation.ts, 6, 24))
>TBar : Symbol(TBar, Decl(typeInferenceCacheInvalidation.ts, 4, 30))

): TCallback
>TCallback : Symbol(TCallback, Decl(typeInferenceCacheInvalidation.ts, 4, 36))

example(42, (foo, bar) => ({
>example : Symbol(example, Decl(typeInferenceCacheInvalidation.ts, 2, 57))
>foo : Symbol(foo, Decl(typeInferenceCacheInvalidation.ts, 10, 13))
>bar : Symbol(bar, Decl(typeInferenceCacheInvalidation.ts, 10, 17))

t: () => {
>t : Symbol(t, Decl(typeInferenceCacheInvalidation.ts, 10, 28))

let s: string = bar;
>s : Symbol(s, Decl(typeInferenceCacheInvalidation.ts, 12, 11))
>bar : Symbol(bar, Decl(typeInferenceCacheInvalidation.ts, 10, 17))
}
}), '42');

example(42, (foo, bar) => ({
>example : Symbol(example, Decl(typeInferenceCacheInvalidation.ts, 2, 57))
>foo : Symbol(foo, Decl(typeInferenceCacheInvalidation.ts, 16, 13))
>bar : Symbol(bar, Decl(typeInferenceCacheInvalidation.ts, 16, 17))

t() {
>t : Symbol(t, Decl(typeInferenceCacheInvalidation.ts, 16, 28))

let s: string = bar;
>s : Symbol(s, Decl(typeInferenceCacheInvalidation.ts, 18, 11))
>bar : Symbol(bar, Decl(typeInferenceCacheInvalidation.ts, 16, 17))
}
}), '42');

63 changes: 63 additions & 0 deletions tests/baselines/reference/typeInferenceCacheInvalidation.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
=== tests/cases/compiler/typeInferenceCacheInvalidation.ts ===
// Repro from #32230

type Callback<TFoo, TBar> = (foo: TFoo, bar: TBar) => any
>Callback : Callback<TFoo, TBar>
>foo : TFoo
>bar : TBar

declare function example<TFoo, TBar, TCallback extends Callback<TFoo, TBar>>(
>example : <TFoo, TBar, TCallback extends Callback<TFoo, TBar>>(foo: TFoo, callback: TCallback, bar: TBar) => TCallback

foo: TFoo,
>foo : TFoo

callback: TCallback,
>callback : TCallback

bar: TBar,
>bar : TBar

): TCallback

example(42, (foo, bar) => ({
>example(42, (foo, bar) => ({ t: () => { let s: string = bar; }}), '42') : (foo: number, bar: string) => { t: () => void; }
>example : <TFoo, TBar, TCallback extends Callback<TFoo, TBar>>(foo: TFoo, callback: TCallback, bar: TBar) => TCallback
>42 : 42
>(foo, bar) => ({ t: () => { let s: string = bar; }}) : (foo: number, bar: string) => { t: () => void; }
>foo : number
>bar : string
>({ t: () => { let s: string = bar; }}) : { t: () => void; }
>{ t: () => { let s: string = bar; }} : { t: () => void; }

t: () => {
>t : () => void
>() => { let s: string = bar; } : () => void

let s: string = bar;
>s : string
>bar : string
}
}), '42');
>'42' : "42"

example(42, (foo, bar) => ({
>example(42, (foo, bar) => ({ t() { let s: string = bar; }}), '42') : (foo: number, bar: string) => { t(): void; }
>example : <TFoo, TBar, TCallback extends Callback<TFoo, TBar>>(foo: TFoo, callback: TCallback, bar: TBar) => TCallback
>42 : 42
>(foo, bar) => ({ t() { let s: string = bar; }}) : (foo: number, bar: string) => { t(): void; }
>foo : number
>bar : string
>({ t() { let s: string = bar; }}) : { t(): void; }
>{ t() { let s: string = bar; }} : { t(): void; }

t() {
>t : () => void

let s: string = bar;
>s : string
>bar : string
}
}), '42');
>'42' : "42"

23 changes: 23 additions & 0 deletions tests/cases/compiler/typeInferenceCacheInvalidation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// @strict: true

// Repro from #32230

type Callback<TFoo, TBar> = (foo: TFoo, bar: TBar) => any

declare function example<TFoo, TBar, TCallback extends Callback<TFoo, TBar>>(
foo: TFoo,
callback: TCallback,
bar: TBar,
): TCallback

example(42, (foo, bar) => ({
t: () => {
let s: string = bar;
}
}), '42');

example(42, (foo, bar) => ({
t() {
let s: string = bar;
}
}), '42');

0 comments on commit 303297a

Please sign in to comment.