From 36e95709333db8d0c9e57b94bbe83347b413b9bb Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 13 Jan 2023 07:23:04 -0800 Subject: [PATCH] Propagate constness of type parameters in variadic tuples (#52129) --- src/compiler/checker.ts | 1 + .../typeParameterConstModifiers.errors.txt | 10 ++++++ .../reference/typeParameterConstModifiers.js | 12 +++++++ .../typeParameterConstModifiers.symbols | 24 ++++++++++++++ .../typeParameterConstModifiers.types | 31 +++++++++++++++++++ .../typeParameterConstModifiers.ts | 10 ++++++ 6 files changed, 88 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 599b4d1ff37..e3ff1665adf 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13256,6 +13256,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function isConstTypeVariable(type: Type): boolean { return !!(type.flags & TypeFlags.TypeParameter && some((type as TypeParameter).symbol?.declarations, d => hasSyntacticModifier(d, ModifierFlags.Const)) || + isGenericTupleType(type) && findIndex(getTypeArguments(type), (t, i) => !!(type.target.elementFlags[i] & ElementFlags.Variadic) && isConstTypeVariable(t)) >= 0 || type.flags & TypeFlags.IndexedAccess && isConstTypeVariable((type as IndexedAccessType).objectType)); } diff --git a/tests/baselines/reference/typeParameterConstModifiers.errors.txt b/tests/baselines/reference/typeParameterConstModifiers.errors.txt index fe5383f5ae4..026c1353c2f 100644 --- a/tests/baselines/reference/typeParameterConstModifiers.errors.txt +++ b/tests/baselines/reference/typeParameterConstModifiers.errors.txt @@ -79,4 +79,14 @@ tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterCon declare let value: "123"; set(obj, ['a', 'b', 'c'], value); + + // Repro from #52007 + + declare function inners(...args: readonly [unknown, ...T, unknown]): T; + + const test = inners(1,2,3,4,5); + + declare function inners2(args: readonly [unknown, ...T, unknown]): T; + + const test2 = inners2([1,2,3,4,5]); \ No newline at end of file diff --git a/tests/baselines/reference/typeParameterConstModifiers.js b/tests/baselines/reference/typeParameterConstModifiers.js index c886c0957ac..cd80513f353 100644 --- a/tests/baselines/reference/typeParameterConstModifiers.js +++ b/tests/baselines/reference/typeParameterConstModifiers.js @@ -71,6 +71,16 @@ declare let obj: Obj; declare let value: "123"; set(obj, ['a', 'b', 'c'], value); + +// Repro from #52007 + +declare function inners(...args: readonly [unknown, ...T, unknown]): T; + +const test = inners(1,2,3,4,5); + +declare function inners2(args: readonly [unknown, ...T, unknown]): T; + +const test2 = inners2([1,2,3,4,5]); //// [typeParameterConstModifiers.js] @@ -105,3 +115,5 @@ var fx1 = function (x) { return x; }; var fx2 = function (x) { return x; }; function set(obj, path, value) { } set(obj, ['a', 'b', 'c'], value); +var test = inners(1, 2, 3, 4, 5); +var test2 = inners2([1, 2, 3, 4, 5]); diff --git a/tests/baselines/reference/typeParameterConstModifiers.symbols b/tests/baselines/reference/typeParameterConstModifiers.symbols index 5a6ca09eecc..6f133ab1558 100644 --- a/tests/baselines/reference/typeParameterConstModifiers.symbols +++ b/tests/baselines/reference/typeParameterConstModifiers.symbols @@ -272,3 +272,27 @@ set(obj, ['a', 'b', 'c'], value); >obj : Symbol(obj, Decl(typeParameterConstModifiers.ts, 68, 11)) >value : Symbol(value, Decl(typeParameterConstModifiers.ts, 69, 11)) +// Repro from #52007 + +declare function inners(...args: readonly [unknown, ...T, unknown]): T; +>inners : Symbol(inners, Decl(typeParameterConstModifiers.ts, 71, 33)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 75, 24)) +>args : Symbol(args, Decl(typeParameterConstModifiers.ts, 75, 56)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 75, 24)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 75, 24)) + +const test = inners(1,2,3,4,5); +>test : Symbol(test, Decl(typeParameterConstModifiers.ts, 77, 5)) +>inners : Symbol(inners, Decl(typeParameterConstModifiers.ts, 71, 33)) + +declare function inners2(args: readonly [unknown, ...T, unknown]): T; +>inners2 : Symbol(inners2, Decl(typeParameterConstModifiers.ts, 77, 31)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 79, 25)) +>args : Symbol(args, Decl(typeParameterConstModifiers.ts, 79, 57)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 79, 25)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 79, 25)) + +const test2 = inners2([1,2,3,4,5]); +>test2 : Symbol(test2, Decl(typeParameterConstModifiers.ts, 81, 5)) +>inners2 : Symbol(inners2, Decl(typeParameterConstModifiers.ts, 77, 31)) + diff --git a/tests/baselines/reference/typeParameterConstModifiers.types b/tests/baselines/reference/typeParameterConstModifiers.types index d7b60bcd110..0cb8b09e199 100644 --- a/tests/baselines/reference/typeParameterConstModifiers.types +++ b/tests/baselines/reference/typeParameterConstModifiers.types @@ -300,3 +300,34 @@ set(obj, ['a', 'b', 'c'], value); >'c' : "c" >value : "123" +// Repro from #52007 + +declare function inners(...args: readonly [unknown, ...T, unknown]): T; +>inners : (...args: readonly [unknown, ...T, unknown]) => T +>args : readonly [unknown, ...T, unknown] + +const test = inners(1,2,3,4,5); +>test : [2, 3, 4] +>inners(1,2,3,4,5) : [2, 3, 4] +>inners : (...args: readonly [unknown, ...T, unknown]) => T +>1 : 1 +>2 : 2 +>3 : 3 +>4 : 4 +>5 : 5 + +declare function inners2(args: readonly [unknown, ...T, unknown]): T; +>inners2 : (args: readonly [unknown, ...T, unknown]) => T +>args : readonly [unknown, ...T, unknown] + +const test2 = inners2([1,2,3,4,5]); +>test2 : [2, 3, 4] +>inners2([1,2,3,4,5]) : [2, 3, 4] +>inners2 : (args: readonly [unknown, ...T, unknown]) => T +>[1,2,3,4,5] : [number, 2, 3, 4, number] +>1 : 1 +>2 : 2 +>3 : 3 +>4 : 4 +>5 : 5 + diff --git a/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiers.ts b/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiers.ts index f84e2cc0fd2..713e0d88568 100644 --- a/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiers.ts +++ b/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiers.ts @@ -72,3 +72,13 @@ declare let obj: Obj; declare let value: "123"; set(obj, ['a', 'b', 'c'], value); + +// Repro from #52007 + +declare function inners(...args: readonly [unknown, ...T, unknown]): T; + +const test = inners(1,2,3,4,5); + +declare function inners2(args: readonly [unknown, ...T, unknown]): T; + +const test2 = inners2([1,2,3,4,5]);