diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2b255da7ae3..441de3a4253 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -28570,10 +28570,6 @@ namespace ts { checkGrammarForDisallowedTrailingComma(parameters, Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma); } - if (isBindingPattern(parameter.name)) { - return grammarErrorOnNode(parameter.name, Diagnostics.A_rest_element_cannot_contain_a_binding_pattern); - } - if (parameter.questionToken) { return grammarErrorOnNode(parameter.questionToken, Diagnostics.A_rest_parameter_cannot_be_optional); } diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index bffdc5809b0..89c87fa82b3 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -1340,8 +1340,8 @@ namespace ts { * part of a constructor declaration with a * synthesized call to `super` */ - function shouldAddRestParameter(node: ParameterDeclaration | undefined, inConstructorWithSynthesizedSuper: boolean) { - return node && node.dotDotDotToken && node.name.kind === SyntaxKind.Identifier && !inConstructorWithSynthesizedSuper; + function shouldAddRestParameter(node: ParameterDeclaration | undefined, inConstructorWithSynthesizedSuper: boolean): node is ParameterDeclaration { + return !!(node && node.dotDotDotToken && !inConstructorWithSynthesizedSuper); } /** @@ -1360,11 +1360,11 @@ namespace ts { } // `declarationName` is the name of the local declaration for the parameter. - const declarationName = getMutableClone(parameter!.name); + const declarationName = parameter.name.kind === SyntaxKind.Identifier ? getMutableClone(parameter.name) : createTempVariable(/*recordTempVariable*/ undefined); setEmitFlags(declarationName, EmitFlags.NoSourceMap); // `expressionName` is the name of the parameter used in expressions. - const expressionName = getSynthesizedClone(parameter!.name); + const expressionName = parameter.name.kind === SyntaxKind.Identifier ? getSynthesizedClone(parameter.name) : declarationName; const restIndex = node.parameters.length - 1; const temp = createLoopVariable(); @@ -1429,6 +1429,24 @@ namespace ts { setEmitFlags(forStatement, EmitFlags.CustomPrologue); startOnNewLine(forStatement); statements.push(forStatement); + + if (parameter.name.kind !== SyntaxKind.Identifier) { + // do the actual destructuring of the rest parameter if necessary + statements.push( + setEmitFlags( + setTextRange( + createVariableStatement( + /*modifiers*/ undefined, + createVariableDeclarationList( + flattenDestructuringBinding(parameter, visitor, context, FlattenLevel.All, expressionName), + ) + ), + parameter + ), + EmitFlags.CustomPrologue + ) + ); + } } /** diff --git a/tests/baselines/reference/iterableArrayPattern14.errors.txt b/tests/baselines/reference/iterableArrayPattern14.errors.txt deleted file mode 100644 index 664f73e13a0..00000000000 --- a/tests/baselines/reference/iterableArrayPattern14.errors.txt +++ /dev/null @@ -1,23 +0,0 @@ -tests/cases/conformance/es6/destructuring/iterableArrayPattern14.ts(16,17): error TS2501: A rest element cannot contain a binding pattern. - - -==== tests/cases/conformance/es6/destructuring/iterableArrayPattern14.ts (1 errors) ==== - class Bar { x } - class Foo extends Bar { y } - class FooIterator { - next() { - return { - value: new Foo, - done: false - }; - } - - [Symbol.iterator]() { - return this; - } - } - - function fun(...[a, ...b]) { } - ~~~~~~~~~ -!!! error TS2501: A rest element cannot contain a binding pattern. - fun(new FooIterator); \ No newline at end of file diff --git a/tests/baselines/reference/iterableArrayPattern15.errors.txt b/tests/baselines/reference/iterableArrayPattern15.errors.txt deleted file mode 100644 index ce7559de94f..00000000000 --- a/tests/baselines/reference/iterableArrayPattern15.errors.txt +++ /dev/null @@ -1,23 +0,0 @@ -tests/cases/conformance/es6/destructuring/iterableArrayPattern15.ts(16,17): error TS2501: A rest element cannot contain a binding pattern. - - -==== tests/cases/conformance/es6/destructuring/iterableArrayPattern15.ts (1 errors) ==== - class Bar { x } - class Foo extends Bar { y } - class FooIterator { - next() { - return { - value: new Foo, - done: false - }; - } - - [Symbol.iterator]() { - return this; - } - } - - function fun(...[a, b]: Bar[]) { } - ~~~~~~ -!!! error TS2501: A rest element cannot contain a binding pattern. - fun(...new FooIterator); \ No newline at end of file diff --git a/tests/baselines/reference/iterableArrayPattern16.errors.txt b/tests/baselines/reference/iterableArrayPattern16.errors.txt index b07d8c976a5..2de26b3a721 100644 --- a/tests/baselines/reference/iterableArrayPattern16.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern16.errors.txt @@ -1,13 +1,10 @@ -tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts(1,17): error TS2501: A rest element cannot contain a binding pattern. tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts(2,5): error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type '[Bar, Bar]'. Property '0' is missing in type 'FooIterator'. tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts(2,12): error TS2449: Class 'FooIteratorIterator' used before its declaration. -==== tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts (3 errors) ==== +==== tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts (2 errors) ==== function fun(...[a, b]: [Bar, Bar][]) { } - ~~~~~~ -!!! error TS2501: A rest element cannot contain a binding pattern. fun(...new FooIteratorIterator); ~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type '[Bar, Bar]'. diff --git a/tests/baselines/reference/iterableArrayPattern17.errors.txt b/tests/baselines/reference/iterableArrayPattern17.errors.txt index d22d8580c71..09f8b8695a7 100644 --- a/tests/baselines/reference/iterableArrayPattern17.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern17.errors.txt @@ -1,9 +1,8 @@ -tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts(16,17): error TS2501: A rest element cannot contain a binding pattern. tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts(17,5): error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type 'Bar'. Property 'x' is missing in type 'FooIterator'. -==== tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts (2 errors) ==== +==== tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts (1 errors) ==== class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -20,8 +19,6 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts(17,5): error } function fun(...[a, b]: Bar[]) { } - ~~~~~~ -!!! error TS2501: A rest element cannot contain a binding pattern. fun(new FooIterator); ~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type 'Bar'. diff --git a/tests/baselines/reference/iterableArrayPattern20.errors.txt b/tests/baselines/reference/iterableArrayPattern20.errors.txt deleted file mode 100644 index 23f133238ce..00000000000 --- a/tests/baselines/reference/iterableArrayPattern20.errors.txt +++ /dev/null @@ -1,23 +0,0 @@ -tests/cases/conformance/es6/destructuring/iterableArrayPattern20.ts(16,17): error TS2501: A rest element cannot contain a binding pattern. - - -==== tests/cases/conformance/es6/destructuring/iterableArrayPattern20.ts (1 errors) ==== - class Bar { x } - class Foo extends Bar { y } - class FooArrayIterator { - next() { - return { - value: [new Foo], - done: false - }; - } - - [Symbol.iterator]() { - return this; - } - } - - function fun(...[[a = new Foo], b = [new Foo]]: Bar[][]) { } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2501: A rest element cannot contain a binding pattern. - fun(...new FooArrayIterator); \ No newline at end of file diff --git a/tests/baselines/reference/iterableArrayPattern25.errors.txt b/tests/baselines/reference/iterableArrayPattern25.errors.txt index 19f2dca07f3..0161be07d4b 100644 --- a/tests/baselines/reference/iterableArrayPattern25.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern25.errors.txt @@ -1,11 +1,8 @@ -tests/cases/conformance/es6/destructuring/iterableArrayPattern25.ts(1,33): error TS2501: A rest element cannot contain a binding pattern. tests/cases/conformance/es6/destructuring/iterableArrayPattern25.ts(2,1): error TS2554: Expected 2 arguments, but got 1. -==== tests/cases/conformance/es6/destructuring/iterableArrayPattern25.ts (2 errors) ==== +==== tests/cases/conformance/es6/destructuring/iterableArrayPattern25.ts (1 errors) ==== function takeFirstTwoEntries(...[[k1, v1], [k2, v2]]) { } - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2501: A rest element cannot contain a binding pattern. takeFirstTwoEntries(new Map([["", 0], ["hello", 1]])); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2554: Expected 2 arguments, but got 1. \ No newline at end of file diff --git a/tests/baselines/reference/iterableArrayPattern26.errors.txt b/tests/baselines/reference/iterableArrayPattern26.errors.txt index a5eff0afb0d..9fb3e688039 100644 --- a/tests/baselines/reference/iterableArrayPattern26.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern26.errors.txt @@ -1,12 +1,9 @@ -tests/cases/conformance/es6/destructuring/iterableArrayPattern26.ts(1,33): error TS2501: A rest element cannot contain a binding pattern. tests/cases/conformance/es6/destructuring/iterableArrayPattern26.ts(2,21): error TS2345: Argument of type 'Map' is not assignable to parameter of type '[string, number]'. Property '0' is missing in type 'Map'. -==== tests/cases/conformance/es6/destructuring/iterableArrayPattern26.ts (2 errors) ==== +==== tests/cases/conformance/es6/destructuring/iterableArrayPattern26.ts (1 errors) ==== function takeFirstTwoEntries(...[[k1, v1], [k2, v2]]: [string, number][]) { } - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2501: A rest element cannot contain a binding pattern. takeFirstTwoEntries(new Map([["", 0], ["hello", 1]])); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type 'Map' is not assignable to parameter of type '[string, number]'. diff --git a/tests/baselines/reference/iterableArrayPattern27.errors.txt b/tests/baselines/reference/iterableArrayPattern27.errors.txt deleted file mode 100644 index 99914ddc508..00000000000 --- a/tests/baselines/reference/iterableArrayPattern27.errors.txt +++ /dev/null @@ -1,8 +0,0 @@ -tests/cases/conformance/es6/destructuring/iterableArrayPattern27.ts(1,33): error TS2501: A rest element cannot contain a binding pattern. - - -==== tests/cases/conformance/es6/destructuring/iterableArrayPattern27.ts (1 errors) ==== - function takeFirstTwoEntries(...[[k1, v1], [k2, v2]]: [string, number][]) { } - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2501: A rest element cannot contain a binding pattern. - takeFirstTwoEntries(...new Map([["", 0], ["hello", 1]])); \ No newline at end of file diff --git a/tests/baselines/reference/iterableArrayPattern28.errors.txt b/tests/baselines/reference/iterableArrayPattern28.errors.txt index 7ca750cd81f..264cb8e7885 100644 --- a/tests/baselines/reference/iterableArrayPattern28.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern28.errors.txt @@ -1,4 +1,3 @@ -tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(1,33): error TS2501: A rest element cannot contain a binding pattern. tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(2,32): error TS2345: Argument of type '([string, number] | [string, boolean])[]' is not assignable to parameter of type 'ReadonlyArray<[string, number]>'. Types of property 'concat' are incompatible. Type '{ (...items: ConcatArray<[string, number] | [string, boolean]>[]): ([string, number] | [string, boolean])[]; (...items: ([string, number] | [string, boolean] | ConcatArray<[string, number] | [string, boolean]>)[]): ([string, number] | [string, boolean])[]; }' is not assignable to type '{ (...items: ConcatArray<[string, number]>[]): [string, number][]; (...items: ([string, number] | ConcatArray<[string, number]>)[]): [string, number][]; }'. @@ -8,10 +7,8 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(2,32): error Type 'boolean' is not assignable to type 'number'. -==== tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts (2 errors) ==== +==== tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts (1 errors) ==== function takeFirstTwoEntries(...[[k1, v1], [k2, v2]]: [string, number][]) { } - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2501: A rest element cannot contain a binding pattern. takeFirstTwoEntries(...new Map([["", 0], ["hello", true]])); ~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '([string, number] | [string, boolean])[]' is not assignable to parameter of type 'ReadonlyArray<[string, number]>'. diff --git a/tests/baselines/reference/iterableArrayPattern29.errors.txt b/tests/baselines/reference/iterableArrayPattern29.errors.txt index 29e5d0d2a3f..a978e357cdf 100644 --- a/tests/baselines/reference/iterableArrayPattern29.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern29.errors.txt @@ -1,12 +1,9 @@ -tests/cases/conformance/es6/destructuring/iterableArrayPattern29.ts(1,33): error TS2501: A rest element cannot contain a binding pattern. tests/cases/conformance/es6/destructuring/iterableArrayPattern29.ts(2,21): error TS2345: Argument of type '[string, boolean]' is not assignable to parameter of type '[string, number]'. Type 'boolean' is not assignable to type 'number'. -==== tests/cases/conformance/es6/destructuring/iterableArrayPattern29.ts (2 errors) ==== +==== tests/cases/conformance/es6/destructuring/iterableArrayPattern29.ts (1 errors) ==== function takeFirstTwoEntries(...[[k1, v1], [k2, v2]]: [string, number][]) { } - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2501: A rest element cannot contain a binding pattern. takeFirstTwoEntries(...new Map([["", true], ["hello", true]])); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '[string, boolean]' is not assignable to parameter of type '[string, number]'. diff --git a/tests/baselines/reference/restParameterWithBindingPattern1.errors.txt b/tests/baselines/reference/restParameterWithBindingPattern1.errors.txt deleted file mode 100644 index 7194159a220..00000000000 --- a/tests/baselines/reference/restParameterWithBindingPattern1.errors.txt +++ /dev/null @@ -1,7 +0,0 @@ -tests/cases/compiler/restParameterWithBindingPattern1.ts(1,15): error TS2501: A rest element cannot contain a binding pattern. - - -==== tests/cases/compiler/restParameterWithBindingPattern1.ts (1 errors) ==== - function a(...{a, b}) { } - ~~~~~~ -!!! error TS2501: A rest element cannot contain a binding pattern. \ No newline at end of file diff --git a/tests/baselines/reference/restParameterWithBindingPattern1.js b/tests/baselines/reference/restParameterWithBindingPattern1.js index 9fb45768afe..eca1a760471 100644 --- a/tests/baselines/reference/restParameterWithBindingPattern1.js +++ b/tests/baselines/reference/restParameterWithBindingPattern1.js @@ -2,4 +2,10 @@ function a(...{a, b}) { } //// [restParameterWithBindingPattern1.js] -function a() { } +function a() { + var _a = []; + for (var _i = 0; _i < arguments.length; _i++) { + _a[_i] = arguments[_i]; + } + var a = _a.a, b = _a.b; +} diff --git a/tests/baselines/reference/restParameterWithBindingPattern2.errors.txt b/tests/baselines/reference/restParameterWithBindingPattern2.errors.txt deleted file mode 100644 index e69e1c2ba78..00000000000 --- a/tests/baselines/reference/restParameterWithBindingPattern2.errors.txt +++ /dev/null @@ -1,7 +0,0 @@ -tests/cases/compiler/restParameterWithBindingPattern2.ts(1,15): error TS2501: A rest element cannot contain a binding pattern. - - -==== tests/cases/compiler/restParameterWithBindingPattern2.ts (1 errors) ==== - function a(...[a, b]) { } - ~~~~~~ -!!! error TS2501: A rest element cannot contain a binding pattern. \ No newline at end of file diff --git a/tests/baselines/reference/restParameterWithBindingPattern2.js b/tests/baselines/reference/restParameterWithBindingPattern2.js index 5c97769acbb..348023d7aa4 100644 --- a/tests/baselines/reference/restParameterWithBindingPattern2.js +++ b/tests/baselines/reference/restParameterWithBindingPattern2.js @@ -2,4 +2,10 @@ function a(...[a, b]) { } //// [restParameterWithBindingPattern2.js] -function a() { } +function a() { + var _a = []; + for (var _i = 0; _i < arguments.length; _i++) { + _a[_i] = arguments[_i]; + } + var a = _a[0], b = _a[1]; +}