Skip to content

Commit 902a32b

Browse files
Copilotjakebaileyahejlsberg
authored
Fix panic when inferring [...rest, ...T] from tuple shorter than fixed-arity constraint (#3917)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com> Co-authored-by: ahejlsberg <4226954+ahejlsberg@users.noreply.github.com>
1 parent 1850f57 commit 902a32b

6 files changed

Lines changed: 84 additions & 4 deletions

File tree

internal/checker/inference.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -727,11 +727,13 @@ func (c *Checker) inferFromObjectTypes(n *InferenceState, source *Type, target *
727727
impliedArity := constraint.TargetTupleType().fixedLength
728728
endIndex := sourceArity - getEndElementCount(target.TargetTupleType(), ElementFlagsFixed)
729729
startIndex := endIndex - impliedArity
730-
trailingSlice := c.createTupleTypeEx(c.getTypeArguments(source)[startIndex:endIndex], source.TargetTupleType().elementInfos[startIndex:endIndex], false /*readonly*/)
731-
if restType := c.getElementTypeOfSliceOfTupleType(source, startLength, endLength+impliedArity, false, false); restType != nil {
732-
c.inferFromTypes(n, restType, elementTypes[startLength])
730+
if startIndex >= startLength {
731+
trailingSlice := c.createTupleTypeEx(c.getTypeArguments(source)[startIndex:endIndex], source.TargetTupleType().elementInfos[startIndex:endIndex], false /*readonly*/)
732+
if restType := c.getElementTypeOfSliceOfTupleType(source, startLength, endLength+impliedArity, false, false); restType != nil {
733+
c.inferFromTypes(n, restType, elementTypes[startLength])
734+
}
735+
c.inferFromTypes(n, trailingSlice, elementTypes[startLength+1])
733736
}
734-
c.inferFromTypes(n, trailingSlice, elementTypes[startLength+1])
735737
}
736738
}
737739
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
inferRestTupleShortSource.ts(7,3): error TS2345: Argument of type '[]' is not assignable to parameter of type '[...string[], string]'.
2+
Source has 0 element(s) but target requires 1.
3+
4+
5+
==== inferRestTupleShortSource.ts (1 errors) ====
6+
// Regression test: tsgo panics when inferring [...rest, ...T] from a tuple shorter than fixed-arity constraint
7+
8+
function f<T extends [string]>(args: [...string[], ...T]) {
9+
// ...
10+
}
11+
12+
f([])
13+
~~
14+
!!! error TS2345: Argument of type '[]' is not assignable to parameter of type '[...string[], string]'.
15+
!!! error TS2345: Source has 0 element(s) but target requires 1.
16+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//// [tests/cases/compiler/inferRestTupleShortSource.ts] ////
2+
3+
//// [inferRestTupleShortSource.ts]
4+
// Regression test: tsgo panics when inferring [...rest, ...T] from a tuple shorter than fixed-arity constraint
5+
6+
function f<T extends [string]>(args: [...string[], ...T]) {
7+
// ...
8+
}
9+
10+
f([])
11+
12+
13+
//// [inferRestTupleShortSource.js]
14+
"use strict";
15+
// Regression test: tsgo panics when inferring [...rest, ...T] from a tuple shorter than fixed-arity constraint
16+
function f(args) {
17+
// ...
18+
}
19+
f([]);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//// [tests/cases/compiler/inferRestTupleShortSource.ts] ////
2+
3+
=== inferRestTupleShortSource.ts ===
4+
// Regression test: tsgo panics when inferring [...rest, ...T] from a tuple shorter than fixed-arity constraint
5+
6+
function f<T extends [string]>(args: [...string[], ...T]) {
7+
>f : Symbol(f, Decl(inferRestTupleShortSource.ts, 0, 0))
8+
>T : Symbol(T, Decl(inferRestTupleShortSource.ts, 2, 11))
9+
>args : Symbol(args, Decl(inferRestTupleShortSource.ts, 2, 31))
10+
>T : Symbol(T, Decl(inferRestTupleShortSource.ts, 2, 11))
11+
12+
// ...
13+
}
14+
15+
f([])
16+
>f : Symbol(f, Decl(inferRestTupleShortSource.ts, 0, 0))
17+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//// [tests/cases/compiler/inferRestTupleShortSource.ts] ////
2+
3+
=== inferRestTupleShortSource.ts ===
4+
// Regression test: tsgo panics when inferring [...rest, ...T] from a tuple shorter than fixed-arity constraint
5+
6+
function f<T extends [string]>(args: [...string[], ...T]) {
7+
>f : <T extends [string]>(args: [...string[], ...T]) => void
8+
>args : [...string[], ...T]
9+
10+
// ...
11+
}
12+
13+
f([])
14+
>f([]) : void
15+
>f : <T extends [string]>(args: [...string[], ...T]) => void
16+
>[] : []
17+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// @strict: true
2+
3+
// Regression test: tsgo panics when inferring [...rest, ...T] from a tuple shorter than fixed-arity constraint
4+
5+
function f<T extends [string]>(args: [...string[], ...T]) {
6+
// ...
7+
}
8+
9+
f([])

0 commit comments

Comments
 (0)