Skip to content

Remove unnecessary check for misaligned complex rest parameters #47934

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17671,10 +17671,6 @@ namespace ts {
if (sourceRestType || targetRestType) {
void instantiateType(sourceRestType || targetRestType, reportUnreliableMarkers);
}
if (sourceRestType && targetRestType && sourceCount !== targetCount) {
// We're not able to relate misaligned complex rest parameters
return Ternary.False;
}

const kind = target.declaration ? target.declaration.kind : SyntaxKind.Unknown;
const strictVariance = !(checkMode & SignatureCheckMode.Callback) && strictFunctionTypes && kind !== SyntaxKind.MethodDeclaration &&
Expand Down
31 changes: 22 additions & 9 deletions tests/baselines/reference/genericRestParameters3.errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(17,11): error TS234
tests/cases/conformance/types/rest/genericRestParameters3.ts(18,1): error TS2345: Argument of type '[]' is not assignable to parameter of type '[string] | [number, boolean]'.
Type '[]' is not assignable to type '[number, boolean]'.
Source has 0 element(s) but target requires 2.
tests/cases/conformance/types/rest/genericRestParameters3.ts(22,1): error TS2322: Type '(x: string, ...args: [string] | [number, boolean]) => void' is not assignable to type '(...args: [string, string] | [string, number, boolean]) => void'.
tests/cases/conformance/types/rest/genericRestParameters3.ts(23,1): error TS2322: Type '(x: string, y: string) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'.
Types of parameters 'y' and 'args' are incompatible.
Type '[string] | [number, boolean]' is not assignable to type '[y: string]'.
Expand All @@ -15,7 +14,6 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(24,1): error TS2322
Type '[string] | [number, boolean]' is not assignable to type '[y: number, z: boolean]'.
Type '[string]' is not assignable to type '[y: number, z: boolean]'.
Source has 1 element(s) but target requires 2.
tests/cases/conformance/types/rest/genericRestParameters3.ts(25,1): error TS2322: Type '(...args: [string, string] | [string, number, boolean]) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'.
tests/cases/conformance/types/rest/genericRestParameters3.ts(35,1): error TS2554: Expected 1 arguments, but got 0.
tests/cases/conformance/types/rest/genericRestParameters3.ts(36,21): error TS2345: Argument of type 'number' is not assignable to parameter of type '(...args: CoolArray<any>) => void'.
tests/cases/conformance/types/rest/genericRestParameters3.ts(37,21): error TS2345: Argument of type '<T extends any[]>(cb: (...args: T) => void) => void' is not assignable to parameter of type '(...args: CoolArray<any>) => void'.
Expand All @@ -36,7 +34,7 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(59,5): error TS2345
Source has 1 element(s) but target requires 2.


==== tests/cases/conformance/types/rest/genericRestParameters3.ts (15 errors) ====
==== tests/cases/conformance/types/rest/genericRestParameters3.ts (13 errors) ====
declare let f1: (x: string, ...args: [string] | [number, boolean]) => void;
declare let f2: (x: string, y: string) => void;
declare let f3: (x: string, y: number, z: boolean) => void;
Expand Down Expand Up @@ -66,9 +64,7 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(59,5): error TS2345

f2 = f1;
f3 = f1;
f4 = f1; // Error, misaligned complex rest types
~~
!!! error TS2322: Type '(x: string, ...args: [string] | [number, boolean]) => void' is not assignable to type '(...args: [string, string] | [string, number, boolean]) => void'.
f4 = f1;
f1 = f2; // Error
~~
!!! error TS2322: Type '(x: string, y: string) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'.
Expand All @@ -83,9 +79,7 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(59,5): error TS2345
!!! error TS2322: Type '[string] | [number, boolean]' is not assignable to type '[y: number, z: boolean]'.
!!! error TS2322: Type '[string]' is not assignable to type '[y: number, z: boolean]'.
!!! error TS2322: Source has 1 element(s) but target requires 2.
f1 = f4; // Error, misaligned complex rest types
~~
!!! error TS2322: Type '(...args: [string, string] | [string, number, boolean]) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'.
f1 = f4;

// Repro from #26110

Expand Down Expand Up @@ -159,4 +153,23 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(59,5): error TS2345
declare function foo2(...args: string[] | number[]): void;
let x2: ReadonlyArray<string> = ["hello"];
foo2(...x2);

// Repros from #47754

type RestParams = [y: string] | [y: number];

type Signature = (x: string, ...rest: RestParams) => void;

type MergedParams = Parameters<Signature>; // [x: string, y: string] | [x: string, y: number]

declare let ff1: (...rest: [string, string] | [string, number]) => void;
declare let ff2: (x: string, ...rest: [string] | [number]) => void;

ff1 = ff2;
ff2 = ff1;

function ff3<A extends unknown[]>(s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void) {
s1 = s2;
s2 = s1;
}

39 changes: 35 additions & 4 deletions tests/baselines/reference/genericRestParameters3.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ f1("foo"); // Error

f2 = f1;
f3 = f1;
f4 = f1; // Error, misaligned complex rest types
f4 = f1;
f1 = f2; // Error
f1 = f3; // Error
f1 = f4; // Error, misaligned complex rest types
f1 = f4;

// Repro from #26110

Expand Down Expand Up @@ -64,6 +64,25 @@ hmm("what"); // no error? A = [] | [number, string] ?
declare function foo2(...args: string[] | number[]): void;
let x2: ReadonlyArray<string> = ["hello"];
foo2(...x2);

// Repros from #47754

type RestParams = [y: string] | [y: number];

type Signature = (x: string, ...rest: RestParams) => void;

type MergedParams = Parameters<Signature>; // [x: string, y: string] | [x: string, y: number]

declare let ff1: (...rest: [string, string] | [string, number]) => void;
declare let ff2: (x: string, ...rest: [string] | [number]) => void;

ff1 = ff2;
ff2 = ff1;

function ff3<A extends unknown[]>(s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void) {
s1 = s2;
s2 = s1;
}


//// [genericRestParameters3.js]
Expand All @@ -87,10 +106,10 @@ f1("foo", 10); // Error
f1("foo"); // Error
f2 = f1;
f3 = f1;
f4 = f1; // Error, misaligned complex rest types
f4 = f1;
f1 = f2; // Error
f1 = f3; // Error
f1 = f4; // Error, misaligned complex rest types
f1 = f4;
foo(); // Error
foo(100); // Error
foo(foo); // Error
Expand All @@ -112,6 +131,12 @@ hmm(1, "s"); // okay, A = [1, "s"]
hmm("what"); // no error? A = [] | [number, string] ?
var x2 = ["hello"];
foo2.apply(void 0, x2);
ff1 = ff2;
ff2 = ff1;
function ff3(s1, s2) {
s1 = s2;
s2 = s1;
}


//// [genericRestParameters3.d.ts]
Expand All @@ -135,3 +160,9 @@ declare const ca: CoolArray<number>;
declare function hmm<A extends [] | [number, string]>(...args: A): void;
declare function foo2(...args: string[] | number[]): void;
declare let x2: ReadonlyArray<string>;
declare type RestParams = [y: string] | [y: number];
declare type Signature = (x: string, ...rest: RestParams) => void;
declare type MergedParams = Parameters<Signature>;
declare let ff1: (...rest: [string, string] | [string, number]) => void;
declare let ff2: (x: string, ...rest: [string] | [number]) => void;
declare function ff3<A extends unknown[]>(s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void): void;
57 changes: 55 additions & 2 deletions tests/baselines/reference/genericRestParameters3.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ f3 = f1;
>f3 : Symbol(f3, Decl(genericRestParameters3.ts, 2, 11))
>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11))

f4 = f1; // Error, misaligned complex rest types
f4 = f1;
>f4 : Symbol(f4, Decl(genericRestParameters3.ts, 3, 11))
>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11))

Expand All @@ -79,7 +79,7 @@ f1 = f3; // Error
>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11))
>f3 : Symbol(f3, Decl(genericRestParameters3.ts, 2, 11))

f1 = f4; // Error, misaligned complex rest types
f1 = f4;
>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11))
>f4 : Symbol(f4, Decl(genericRestParameters3.ts, 3, 11))

Expand Down Expand Up @@ -190,3 +190,56 @@ foo2(...x2);
>foo2 : Symbol(foo2, Decl(genericRestParameters3.ts, 58, 12))
>x2 : Symbol(x2, Decl(genericRestParameters3.ts, 63, 3))

// Repros from #47754

type RestParams = [y: string] | [y: number];
>RestParams : Symbol(RestParams, Decl(genericRestParameters3.ts, 64, 12))

type Signature = (x: string, ...rest: RestParams) => void;
>Signature : Symbol(Signature, Decl(genericRestParameters3.ts, 68, 44))
>x : Symbol(x, Decl(genericRestParameters3.ts, 70, 18))
>rest : Symbol(rest, Decl(genericRestParameters3.ts, 70, 28))
>RestParams : Symbol(RestParams, Decl(genericRestParameters3.ts, 64, 12))

type MergedParams = Parameters<Signature>; // [x: string, y: string] | [x: string, y: number]
>MergedParams : Symbol(MergedParams, Decl(genericRestParameters3.ts, 70, 58))
>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --))
>Signature : Symbol(Signature, Decl(genericRestParameters3.ts, 68, 44))

declare let ff1: (...rest: [string, string] | [string, number]) => void;
>ff1 : Symbol(ff1, Decl(genericRestParameters3.ts, 74, 11))
>rest : Symbol(rest, Decl(genericRestParameters3.ts, 74, 18))

declare let ff2: (x: string, ...rest: [string] | [number]) => void;
>ff2 : Symbol(ff2, Decl(genericRestParameters3.ts, 75, 11))
>x : Symbol(x, Decl(genericRestParameters3.ts, 75, 18))
>rest : Symbol(rest, Decl(genericRestParameters3.ts, 75, 28))

ff1 = ff2;
>ff1 : Symbol(ff1, Decl(genericRestParameters3.ts, 74, 11))
>ff2 : Symbol(ff2, Decl(genericRestParameters3.ts, 75, 11))

ff2 = ff1;
>ff2 : Symbol(ff2, Decl(genericRestParameters3.ts, 75, 11))
>ff1 : Symbol(ff1, Decl(genericRestParameters3.ts, 74, 11))

function ff3<A extends unknown[]>(s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void) {
>ff3 : Symbol(ff3, Decl(genericRestParameters3.ts, 78, 10))
>A : Symbol(A, Decl(genericRestParameters3.ts, 80, 13))
>s1 : Symbol(s1, Decl(genericRestParameters3.ts, 80, 34))
>args : Symbol(args, Decl(genericRestParameters3.ts, 80, 39))
>A : Symbol(A, Decl(genericRestParameters3.ts, 80, 13))
>s2 : Symbol(s2, Decl(genericRestParameters3.ts, 80, 92))
>x : Symbol(x, Decl(genericRestParameters3.ts, 80, 98))
>rest : Symbol(rest, Decl(genericRestParameters3.ts, 80, 108))
>A : Symbol(A, Decl(genericRestParameters3.ts, 80, 13))

s1 = s2;
>s1 : Symbol(s1, Decl(genericRestParameters3.ts, 80, 34))
>s2 : Symbol(s2, Decl(genericRestParameters3.ts, 80, 92))

s2 = s1;
>s2 : Symbol(s2, Decl(genericRestParameters3.ts, 80, 92))
>s1 : Symbol(s1, Decl(genericRestParameters3.ts, 80, 34))
}

55 changes: 53 additions & 2 deletions tests/baselines/reference/genericRestParameters3.types
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ f3 = f1;
>f3 : (x: string, y: number, z: boolean) => void
>f1 : (x: string, ...args: [string] | [number, boolean]) => void

f4 = f1; // Error, misaligned complex rest types
f4 = f1;
>f4 = f1 : (x: string, ...args: [string] | [number, boolean]) => void
>f4 : (...args: [string, string] | [string, number, boolean]) => void
>f1 : (x: string, ...args: [string] | [number, boolean]) => void
Expand All @@ -108,7 +108,7 @@ f1 = f3; // Error
>f1 : (x: string, ...args: [string] | [number, boolean]) => void
>f3 : (x: string, y: number, z: boolean) => void

f1 = f4; // Error, misaligned complex rest types
f1 = f4;
>f1 = f4 : (...args: [string, string] | [string, number, boolean]) => void
>f1 : (x: string, ...args: [string] | [number, boolean]) => void
>f4 : (...args: [string, string] | [string, number, boolean]) => void
Expand Down Expand Up @@ -227,3 +227,54 @@ foo2(...x2);
>...x2 : string
>x2 : readonly string[]

// Repros from #47754

type RestParams = [y: string] | [y: number];
>RestParams : RestParams

type Signature = (x: string, ...rest: RestParams) => void;
>Signature : Signature
>x : string
>rest : RestParams

type MergedParams = Parameters<Signature>; // [x: string, y: string] | [x: string, y: number]
>MergedParams : [x: string, y: string] | [x: string, y: number]

declare let ff1: (...rest: [string, string] | [string, number]) => void;
>ff1 : (...rest: [string, string] | [string, number]) => void
>rest : [string, string] | [string, number]

declare let ff2: (x: string, ...rest: [string] | [number]) => void;
>ff2 : (x: string, ...rest: [string] | [number]) => void
>x : string
>rest : [string] | [number]

ff1 = ff2;
>ff1 = ff2 : (x: string, ...rest: [string] | [number]) => void
>ff1 : (...rest: [string, string] | [string, number]) => void
>ff2 : (x: string, ...rest: [string] | [number]) => void

ff2 = ff1;
>ff2 = ff1 : (...rest: [string, string] | [string, number]) => void
>ff2 : (x: string, ...rest: [string] | [number]) => void
>ff1 : (...rest: [string, string] | [string, number]) => void

function ff3<A extends unknown[]>(s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void) {
>ff3 : <A extends unknown[]>(s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void) => void
>s1 : (...args: [x: string, ...rest: A | [number]]) => void
>args : [string, number] | [x: string, ...rest: A]
>s2 : (x: string, ...rest: A | [number]) => void
>x : string
>rest : [number] | A

s1 = s2;
>s1 = s2 : (x: string, ...rest: [number] | A) => void
>s1 : (...args: [string, number] | [x: string, ...rest: A]) => void
>s2 : (x: string, ...rest: [number] | A) => void

s2 = s1;
>s2 = s1 : (...args: [string, number] | [x: string, ...rest: A]) => void
>s2 : (x: string, ...rest: [number] | A) => void
>s1 : (...args: [string, number] | [x: string, ...rest: A]) => void
}

23 changes: 21 additions & 2 deletions tests/cases/conformance/types/rest/genericRestParameters3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ f1("foo"); // Error

f2 = f1;
f3 = f1;
f4 = f1; // Error, misaligned complex rest types
f4 = f1;
f1 = f2; // Error
f1 = f3; // Error
f1 = f4; // Error, misaligned complex rest types
f1 = f4;

// Repro from #26110

Expand Down Expand Up @@ -66,3 +66,22 @@ hmm("what"); // no error? A = [] | [number, string] ?
declare function foo2(...args: string[] | number[]): void;
let x2: ReadonlyArray<string> = ["hello"];
foo2(...x2);

// Repros from #47754

type RestParams = [y: string] | [y: number];

type Signature = (x: string, ...rest: RestParams) => void;

type MergedParams = Parameters<Signature>; // [x: string, y: string] | [x: string, y: number]

declare let ff1: (...rest: [string, string] | [string, number]) => void;
declare let ff2: (x: string, ...rest: [string] | [number]) => void;

ff1 = ff2;
ff2 = ff1;

function ff3<A extends unknown[]>(s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void) {
s1 = s2;
s2 = s1;
}