From 9b2b2ca19b4b0a3dcc2113b79a20e84cde01877c Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 11 Nov 2016 08:56:35 -0800 Subject: [PATCH 1/2] Error on non-identifier rest in destructuring assignment --- src/compiler/checker.ts | 7 ++++++- src/compiler/diagnosticMessages.json | 4 ++++ src/compiler/transformers/destructuring.ts | 5 +++-- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7bd8dfae88b..789f2bd8104 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13941,7 +13941,12 @@ namespace ts { error(name, Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(objectLiteralType), declarationNameToString(name)); } } - else if (property.kind !== SyntaxKind.SpreadAssignment) { + else if (property.kind === SyntaxKind.SpreadAssignment) { + if (property.expression.kind !== SyntaxKind.Identifier) { + error(property.expression, Diagnostics.An_object_rest_element_must_be_an_identifier); + } + } + else { error(property, Diagnostics.Property_assignment_expected); } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 921c80eec08..ce5e59e509c 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1991,6 +1991,10 @@ "category": "Error", "code": 2700 }, + "An object rest element must be an identifier.": { + "category": "Error", + "code": 2701 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index bba09710898..a8c00776741 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -328,8 +328,9 @@ namespace ts { bindingElements.push(p); } } - else if (i === properties.length - 1 && p.kind === SyntaxKind.SpreadAssignment) { - Debug.assert((p as SpreadAssignment).expression.kind === SyntaxKind.Identifier); + else if (i === properties.length - 1 && + p.kind === SyntaxKind.SpreadAssignment && + p.expression.kind === SyntaxKind.Identifier) { if (bindingElements.length) { emitRestAssignment(bindingElements, value, location, target); bindingElements = []; From de9f59a3019030493a49bbf2f32900574ec74591 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 11 Nov 2016 08:57:11 -0800 Subject: [PATCH 2/2] Test non-identifier rest in destructuring assignment --- tests/baselines/reference/objectRestNegative.errors.txt | 8 +++++++- tests/baselines/reference/objectRestNegative.js | 5 +++++ tests/cases/conformance/types/rest/objectRestNegative.ts | 3 +++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/tests/baselines/reference/objectRestNegative.errors.txt b/tests/baselines/reference/objectRestNegative.errors.txt index 1874570da7c..b8144e3209b 100644 --- a/tests/baselines/reference/objectRestNegative.errors.txt +++ b/tests/baselines/reference/objectRestNegative.errors.txt @@ -1,9 +1,10 @@ tests/cases/conformance/types/rest/objectRestNegative.ts(2,10): error TS2462: A rest element must be last in a destructuring pattern tests/cases/conformance/types/rest/objectRestNegative.ts(3,31): error TS2462: A rest element must be last in a destructuring pattern tests/cases/conformance/types/rest/objectRestNegative.ts(6,17): error TS2700: Rest types may only be created from object types. +tests/cases/conformance/types/rest/objectRestNegative.ts(11,9): error TS2701: An object rest element must be an identifier. -==== tests/cases/conformance/types/rest/objectRestNegative.ts (3 errors) ==== +==== tests/cases/conformance/types/rest/objectRestNegative.ts (4 errors) ==== let o = { a: 1, b: 'no' }; var { ...mustBeLast, a } = o; ~~~~~~~~~~ @@ -18,4 +19,9 @@ tests/cases/conformance/types/rest/objectRestNegative.ts(6,17): error TS2700: Re !!! error TS2700: Rest types may only be created from object types. return rest; } + + let rest: { b: string } + ({a, ...rest.b + rest.b} = o); + ~~~~~~~~~~~~~~~ +!!! error TS2701: An object rest element must be an identifier. \ No newline at end of file diff --git a/tests/baselines/reference/objectRestNegative.js b/tests/baselines/reference/objectRestNegative.js index b3b49740762..8692850dbdd 100644 --- a/tests/baselines/reference/objectRestNegative.js +++ b/tests/baselines/reference/objectRestNegative.js @@ -7,6 +7,9 @@ function generic(t: T) { let { x, ...rest } = t; return rest; } + +let rest: { b: string } +({a, ...rest.b + rest.b} = o); //// [objectRestNegative.js] @@ -25,3 +28,5 @@ function generic(t) { var x = t.x, rest = __rest(t, ["x"]); return rest; } +var rest; +(a = o.a, o, o); diff --git a/tests/cases/conformance/types/rest/objectRestNegative.ts b/tests/cases/conformance/types/rest/objectRestNegative.ts index 7296f2d274e..75cbe9a55e4 100644 --- a/tests/cases/conformance/types/rest/objectRestNegative.ts +++ b/tests/cases/conformance/types/rest/objectRestNegative.ts @@ -6,3 +6,6 @@ function generic(t: T) { let { x, ...rest } = t; return rest; } + +let rest: { b: string } +({a, ...rest.b + rest.b} = o);