diff --git a/test/language/expressions/assignment/destructuring/array-elem-iter-get-err.js b/test/language/expressions/assignment/destructuring/array-elem-iter-get-err.js
new file mode 100644
index 0000000000000000000000000000000000000000..2f545842fdec310241fe1ea53082a1052d024cd4
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-iter-get-err.js
@@ -0,0 +1,23 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Abrupt completion returned from GetIterator
+info: |
+    ArrayAssignmentPattern : [ AssignmentElementList ]
+
+    1. Let iterator be GetIterator(value).
+    2. ReturnIfAbrupt(iterator).
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var iterable = {};
+iterable[Symbol.iterator] = function() {
+  throw new Test262Error();
+};
+var x;
+
+assert.throws(Test262Error, function() {
+  [ x ] = iterable;
+});
diff --git a/test/language/expressions/assignment/destructuring/array-elem-iter-nrml-close-err.js b/test/language/expressions/assignment/destructuring/array-elem-iter-nrml-close-err.js
new file mode 100644
index 0000000000000000000000000000000000000000..414495122ca13bd92fec79be6f486c5c0f42ad20
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-iter-nrml-close-err.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Abrupt completion returned from IteratorClose
+info: |
+    ArrayAssignmentPattern : [ AssignmentElementList ]
+
+    [...]
+    5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator, result).
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var x;
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    // Set an upper-bound to limit unnecessary iteration in non-conformant
+    // implementations
+    return { done: nextCount > 10 };
+  },
+  return: function() {
+    returnCount += 1;
+    throw new Test262Error();
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(Test262Error, function() {
+  [ x ] = iterable;
+});
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
diff --git a/test/language/expressions/assignment/destructuring/array-elem-iter-nrml-close-null.js b/test/language/expressions/assignment/destructuring/array-elem-iter-nrml-close-null.js
new file mode 100644
index 0000000000000000000000000000000000000000..67e3ead4d0d579817c4c7009c21ca3f307b20976
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-iter-nrml-close-null.js
@@ -0,0 +1,47 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose throws a TypeError when `return` returns a non-Object value
+info: |
+    ArrayAssignmentPattern : [ AssignmentElementList ]
+
+    [...]
+    5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+    6. Return result.
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    7. If completion.[[type]] is throw, return Completion(completion).
+    8. If innerResult.[[type]] is throw, return Completion(innerResult).
+    9. If Type(innerResult.[[value]]) is not Object, throw a TypeError
+       exception.
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var x;
+var iterable = {};
+var nextCount = 0;
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    // Set an upper-bound to limit unnecessary iteration in non-conformant
+    // implementations
+    return { done: nextCount > 10 };
+  },
+  return: function() {
+    return null;
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(TypeError, function() {
+  [ x ] = iterable;
+});
diff --git a/test/language/expressions/assignment/destructuring/array-elem-iter-nrml-close-skip.js b/test/language/expressions/assignment/destructuring/array-elem-iter-nrml-close-skip.js
new file mode 100644
index 0000000000000000000000000000000000000000..c3b2087e8b0b2c313456741f8b62b2c9ca1028a5
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-iter-nrml-close-skip.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is not called when assignment evaluation has exhausted the
+    iterator
+info: |
+    ArrayAssignmentPattern : [ AssignmentElementList ]
+
+    [...]
+    5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator, result).
+    6. Return result.
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var x;
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    return { done: true };
+  },
+  return: function() {
+    returnCount += 1;
+    return {};
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+[ x ] = iterable;
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
diff --git a/test/language/expressions/assignment/destructuring/array-elem-iter-nrml-close.js b/test/language/expressions/assignment/destructuring/array-elem-iter-nrml-close.js
new file mode 100644
index 0000000000000000000000000000000000000000..80f9902b03a7db0749619d490a66a54dab52f741
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-iter-nrml-close.js
@@ -0,0 +1,55 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is called when assignment evaluation has not exhausted the
+    iterator
+info: |
+    ArrayAssignmentPattern : [ AssignmentElementList ]
+
+    [...]
+    5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+    6. Return result.
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    [...]
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var thisValue = null;
+var args = null;
+var x;
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    // Set an upper-bound to limit unnecessary iteration in non-conformant
+    // implementations
+    return { done: nextCount > 10 };
+  },
+  return: function() {
+    returnCount += 1;
+    thisValue = this;
+    args = arguments;
+    return {};
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+[ x ] = iterable;
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
+assert.sameValue(thisValue, iterator, 'correct `this` value');
+assert(!!args, 'arguments object provided');
+assert.sameValue(args.length, 0, 'zero arguments specified');
diff --git a/test/language/expressions/assignment/destructuring/array-elem-iter-rtrn-close-err.js b/test/language/expressions/assignment/destructuring/array-elem-iter-rtrn-close-err.js
new file mode 100644
index 0000000000000000000000000000000000000000..4b3b2a36ae75b0623dd3c6178be83806f413777f
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-iter-rtrn-close-err.js
@@ -0,0 +1,51 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is called when reference evaluation produces a "return"
+    completion
+info: |
+    ArrayAssignmentPattern : [ AssignmentElementList ]
+
+    [...]
+    5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+    6. Return result.
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    7. If completion.[[type]] is throw, return Completion(completion).
+    8. If innerResult.[[type]] is throw, return Completion(innerResult).
+features: [Symbol.iterator, generators]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var returnCount = 0;
+var unreachable = 0;
+var iterable = {};
+var iterator = {
+  return: function() {
+    returnCount += 1;
+    throw new Test262Error();
+  }
+};
+var iter;
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+function* g() {
+  [ {}[yield] ] = iterable;
+  unreachable += 1;
+}
+iter = g();
+iter.next();
+assert.throws(Test262Error, function() {
+  iter.return();
+});
+
+assert.sameValue(returnCount, 1);
+assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
diff --git a/test/language/expressions/assignment/destructuring/array-elem-iter-rtrn-close-null.js b/test/language/expressions/assignment/destructuring/array-elem-iter-rtrn-close-null.js
new file mode 100644
index 0000000000000000000000000000000000000000..4e95868e8c4bc681a4685c2c81cd0a21a79d9aac
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-iter-rtrn-close-null.js
@@ -0,0 +1,47 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose throws a TypeError when `return` returns a non-Object value
+info: |
+    ArrayAssignmentPattern : [ AssignmentElementList ]
+
+    [...]
+    5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+    6. Return result.
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    7. If completion.[[type]] is throw, return Completion(completion).
+    8. If innerResult.[[type]] is throw, return Completion(innerResult).
+    9. If Type(innerResult.[[value]]) is not Object, throw a TypeError
+       exception.
+features: [Symbol.iterator, generators]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var iterable = {};
+var iterator = {
+  return: function() {
+    return null;
+  }
+};
+var iter;
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+function* g() {
+  [ {}[yield] ] = iterable;
+  unreachable += 1;
+}
+
+iter = g();
+iter.next();
+
+assert.throws(TypeError, function() {
+  iter.return();
+});
diff --git a/test/language/expressions/assignment/destructuring/array-elem-iter-rtrn-close.js b/test/language/expressions/assignment/destructuring/array-elem-iter-rtrn-close.js
new file mode 100644
index 0000000000000000000000000000000000000000..2d9380de2053f86b0d8a1c7a293efc07792adde3
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-iter-rtrn-close.js
@@ -0,0 +1,58 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is called when reference evaluation produces a "return"
+    completion
+info: |
+    ArrayAssignmentPattern : [ AssignmentElementList ]
+
+    [...]
+    5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+    6. Return result.
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    7. If completion.[[type]] is throw, return Completion(completion).
+    8. If innerResult.[[type]] is throw, return Completion(innerResult).
+features: [Symbol.iterator, generators]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var returnCount = 0;
+var unreachable = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var iterator = {
+  return: function() {
+    returnCount += 1;
+    thisValue = this;
+    args = arguments;
+    return {};
+  }
+};
+var iter, result;
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+function* g() {
+  [ {}[yield] ] = iterable;
+  unreachable += 1;
+}
+iter = g();
+iter.next();
+result = iter.return(777);
+
+assert.sameValue(returnCount, 1);
+assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
+assert.sameValue(result.value, 777);
+assert(result.done, 'Iterator correctly closed');
+assert.sameValue(thisValue, iterator, 'correct `this` value');
+assert(!!args, 'arguments object provided');
+assert.sameValue(args.length, 0, 'zero arguments specified');
diff --git a/test/language/expressions/assignment/destructuring/array-elem-iter-thrw-close-err.js b/test/language/expressions/assignment/destructuring/array-elem-iter-thrw-close-err.js
new file mode 100644
index 0000000000000000000000000000000000000000..d92f9a4359970bcd815710d76916b8558c525421
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-iter-thrw-close-err.js
@@ -0,0 +1,47 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is called when reference evaluation produces a "throw"
+    completion
+info: |
+    ArrayAssignmentPattern : [ AssignmentElementList ]
+
+    [...]
+    5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+    6. Return result.
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+function ReturnError() {}
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    return { done: true };
+  },
+  return: function() {
+    returnCount += 1;
+
+    // This value should be discarded.
+    throw new ReturnError();
+  }
+};
+var thrower = function() {
+  throw new Test262Error();
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(Test262Error, function() {
+  [ {}[thrower()] ] = iterable;
+});
+
+assert.sameValue(nextCount, 0);
+assert.sameValue(returnCount, 1);
diff --git a/test/language/expressions/assignment/destructuring/array-elem-iter-thrw-close-skip.js b/test/language/expressions/assignment/destructuring/array-elem-iter-thrw-close-skip.js
new file mode 100644
index 0000000000000000000000000000000000000000..fc27f58e38d58458f6fcd7b6d5a29bcd46fa2247
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-iter-thrw-close-skip.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is not called when iteration produces an abrupt completion
+info: |
+    ArrayAssignmentPattern : [ AssignmentElementList ]
+
+    [...]
+    5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+    6. Return result.
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    throw new Test262Error();
+  },
+  return: function() {
+    returnCount += 1;
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+var x;
+
+assert.throws(Test262Error, function() {
+  [ x ] = iterable;
+});
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
diff --git a/test/language/expressions/assignment/destructuring/array-elem-iter-thrw-close.js b/test/language/expressions/assignment/destructuring/array-elem-iter-thrw-close.js
new file mode 100644
index 0000000000000000000000000000000000000000..4474c432fc36ffd9573af3dc95cf20fc5af8a122
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-iter-thrw-close.js
@@ -0,0 +1,56 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is called when reference evaluation produces a "throw"
+    completion
+info: |
+    ArrayAssignmentPattern : [ AssignmentElementList ]
+
+    [...]
+    5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+    6. Return result.
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    [...]
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    return { done: true };
+  },
+  return: function() {
+    returnCount += 1;
+    thisValue = this;
+    args = arguments;
+  }
+};
+var thrower = function() {
+  throw new Test262Error();
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(Test262Error, function() {
+  [ {}[thrower()] ] = iterable;
+});
+
+assert.sameValue(nextCount, 0);
+assert.sameValue(returnCount, 1);
+assert.sameValue(thisValue, iterator, 'correct `this` value');
+assert(!!args, 'arguments object provided');
+assert.sameValue(args.length, 0, 'zero arguments specified');
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-elision-iter-abpt.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-elision-iter-abpt.js
new file mode 100644
index 0000000000000000000000000000000000000000..c4624b2c48109267299735651ae59bd4433c2421
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-elision-iter-abpt.js
@@ -0,0 +1,52 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Abrupt completion returned during evaluation of elision
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    [...]
+    6. If Elision is present, then
+       a. Let status be the result of performing
+          IteratorDestructuringAssignmentEvaluation of Elision with
+          iteratorRecord as the argument.
+       b. If status is an abrupt completion, then
+          i. If iteratorRecord.[[done]] is false, return
+             IteratorClose(iterator, status).
+          ii. Return Completion(status).
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var x;
+var iterator = {
+  next: function() {
+    nextCount += 1;
+
+    if (nextCount === 2) {
+      throw new Test262Error();
+    }
+
+    // Set an upper-bound to limit unnecessary iteration in non-conformant
+    // implementations
+    return { done: nextCount > 10 };
+  },
+  return: function() {
+    returnCount += 1;
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(Test262Error, function() {
+  [ x , , ] = iterable;
+});
+
+assert.sameValue(nextCount, 2);
+assert.sameValue(returnCount, 0);
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-elision-iter-nrml-close-err.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-elision-iter-nrml-close-err.js
new file mode 100644
index 0000000000000000000000000000000000000000..abb0aa22bbf9312399004ea8a9fb7f22b39cec69
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-elision-iter-nrml-close-err.js
@@ -0,0 +1,49 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Abrupt completion returned from IteratorClose
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    [...]
+    6. If Elision is present, then
+       a. Let status be the result of performing
+          IteratorDestructuringAssignmentEvaluation of Elision with
+          iteratorRecord as the argument.
+       b. If status is an abrupt completion, then
+          [...]
+    8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       status).
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var x;
+var iterator = {
+  next: function() {
+    nextCount += 1;
+
+    // Set an upper-bound to limit unnecessary iteration in non-conformant
+    // implementations
+    return { done: nextCount > 10 };
+  },
+  return: function() {
+    returnCount += 1;
+    throw new Test262Error();
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(Test262Error, function() {
+  [ x , , ] = iterable;
+});
+
+assert.sameValue(nextCount, 2);
+assert.sameValue(returnCount, 1);
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-elision-iter-nrml-close-null.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-elision-iter-nrml-close-null.js
new file mode 100644
index 0000000000000000000000000000000000000000..edb875d5e6b1a6d685e17b6001eb38b4ebe36b6c
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-elision-iter-nrml-close-null.js
@@ -0,0 +1,53 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose throws a TypeError when `return` returns a non-Object value
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    [...]
+    6. If Elision is present, then
+       a. Let status be the result of performing
+          IteratorDestructuringAssignmentEvaluation of Elision with
+          iteratorRecord as the argument.
+       b. If status is an abrupt completion, then
+          [...]
+    8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       status).
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    7. If completion.[[type]] is throw, return Completion(completion).
+    8. If innerResult.[[type]] is throw, return Completion(innerResult).
+    9. If Type(innerResult.[[value]]) is not Object, throw a TypeError
+       exception.
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var iterable = {};
+var x;
+var nextCount = 0;
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    // Set an upper-bound to limit unnecessary iteration in non-conformant
+    // implementations
+    return { done: nextCount > 10 };
+  },
+  return: function() {
+    return null;
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(TypeError, function() {
+  [ x , , ] = iterable;
+});
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-elision-iter-nrml-close-skip.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-elision-iter-nrml-close-skip.js
new file mode 100644
index 0000000000000000000000000000000000000000..e1ba46661f39ab4b9c774c73db393dc61ac525d3
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-elision-iter-nrml-close-skip.js
@@ -0,0 +1,45 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: IteratorClose not invoked when elision exhausts the iterator
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    [...]
+    6. If Elision is present, then
+       a. Let status be the result of performing
+          IteratorDestructuringAssignmentEvaluation of Elision with
+          iteratorRecord as the argument.
+       b. If status is an abrupt completion, then
+          [...]
+    8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       status).
+    9. Return Completion(status).
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var x;
+var iterator = {
+  next: function() {
+    nextCount += 1;
+
+    return { done: nextCount > 1 };
+  },
+  return: function() {
+    returnCount += 1;
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+[ x , , ] = iterable;
+
+assert.sameValue(nextCount, 2);
+assert.sameValue(returnCount, 0);
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-elision-iter-nrml-close.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-elision-iter-nrml-close.js
new file mode 100644
index 0000000000000000000000000000000000000000..b7846bb1abe28ac06409a531d85f7b71f7659790
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-elision-iter-nrml-close.js
@@ -0,0 +1,60 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: IteratorClose invoked when elision does not exhaust the iterator
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    [...]
+    6. If Elision is present, then
+       a. Let status be the result of performing
+          IteratorDestructuringAssignmentEvaluation of Elision with
+          iteratorRecord as the argument.
+       b. If status is an abrupt completion, then
+          [...]
+    8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       status).
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    [...]
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var x;
+var iterator = {
+  next: function() {
+    nextCount += 1;
+
+    // Set an upper-bound to limit unnecessary iteration in non-conformant
+    // implementations
+    return { done: nextCount > 10 };
+  },
+  return: function() {
+    returnCount += 1;
+    thisValue = this;
+    args = arguments;
+    return {};
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+[ x , , ] = iterable;
+
+assert.sameValue(nextCount, 2);
+assert.sameValue(returnCount, 1);
+assert.sameValue(thisValue, iterator, 'correct `this` value');
+assert(!!args, 'arguments object provided');
+assert.sameValue(args.length, 0, 'zero arguments specified');
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-get-err.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-get-err.js
new file mode 100644
index 0000000000000000000000000000000000000000..7a3e3a9a3a4c2e7286cb4b551295e526fbd47f1e
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-get-err.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Abrupt completion returned from GetIterator
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    1. Let iterator be GetIterator(value).
+    2. ReturnIfAbrupt(iterator).
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var iterable = {};
+iterable[Symbol.iterator] = function() {
+  throw new Test262Error();
+};
+var x;
+
+assert.throws(Test262Error, function() {
+  [ x , ] = iterable;
+});
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-nrml-close-err.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-nrml-close-err.js
new file mode 100644
index 0000000000000000000000000000000000000000..491d91e86c2ef75a466d2df23452bec6f787d62f
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-nrml-close-err.js
@@ -0,0 +1,49 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Abrupt completion returned from IteratorClose
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    [...]
+    3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
+    4. Let status be the result of performing
+       IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
+       iteratorRecord as the argument.
+    5. If status is an abrupt completion, then
+       a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+          status).
+       b. Return Completion(status).
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var thrower = function() {
+  throw new Test262Error();
+};
+var x;
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    return { done: nextCount > 10 };
+  },
+  return: function() {
+    returnCount += 1;
+    throw new Test262Error();
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(Test262Error, function() {
+  [ x , ] = iterable;
+});
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-nrml-close-null.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-nrml-close-null.js
new file mode 100644
index 0000000000000000000000000000000000000000..daa2b227b3713b89f710e999a26bf43407994a91
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-nrml-close-null.js
@@ -0,0 +1,53 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose throws a TypeError when `return` returns a non-Object value
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    [...]
+    3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
+    4. Let status be the result of performing
+       IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
+       iteratorRecord as the argument.
+    5. If status is an abrupt completion, then
+       a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+          status).
+       b. Return Completion(status).
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    7. If completion.[[type]] is throw, return Completion(completion).
+    8. If innerResult.[[type]] is throw, return Completion(innerResult).
+    9. If Type(innerResult.[[value]]) is not Object, throw a TypeError
+       exception.
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var iterable = {};
+var x;
+var nextCount = 0;
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    // Set an upper-bound to limit unnecessary iteration in non-conformant
+    // implementations
+    return { done: nextCount > 10 };
+  },
+  return: function() {
+    return null;
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(TypeError, function() {
+  [ x , ] = iterable;
+});
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-nrml-close-skip.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-nrml-close-skip.js
new file mode 100644
index 0000000000000000000000000000000000000000..a7b0f41c068ea1115ccc6c5f240546a8691f9628
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-nrml-close-skip.js
@@ -0,0 +1,48 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is not invoked when evaluation of AssignmentElementList
+    exhausts the iterator
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    [...]
+    3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
+    4. Let status be the result of performing
+       IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
+       iteratorRecord as the argument.
+    5. If status is an abrupt completion, then
+       a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+          status).
+       b. Return Completion(status).
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var thrower = function() {
+  throw new Test262Error();
+};
+var x;
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    return { done: true };
+  },
+  return: function() {
+    returnCount += 1;
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+[ x , ] = iterable;
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-nrml-close.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-nrml-close.js
new file mode 100644
index 0000000000000000000000000000000000000000..76582ec71b60c14b7951fc15ea857dfd34543bbd
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-nrml-close.js
@@ -0,0 +1,61 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is invoked when evaluation of AssignmentElementList completes
+    without exhausting the iterator
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    [...]
+    3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
+    4. Let status be the result of performing
+       IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
+       iteratorRecord as the argument.
+    5. If status is an abrupt completion, then
+       a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+          status).
+       b. Return Completion(status).
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    [...]
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var x;
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    // Set an upper-bound to limit unnecessary iteration in non-conformant
+    // implementations
+    return { done: nextCount > 10 };
+  },
+  return: function() {
+    returnCount += 1;
+    thisValue = this;
+    args = arguments;
+    return {};
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+[ x , ] = iterable;
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
+assert.sameValue(thisValue, iterator, 'correct `this` value');
+assert(!!args, 'arguments object provided');
+assert.sameValue(args.length, 0, 'zero arguments specified');
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-rtrn-close-err.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-rtrn-close-err.js
new file mode 100644
index 0000000000000000000000000000000000000000..7591e15c5e22539fb0e6455ba12df2865a2cee45
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-rtrn-close-err.js
@@ -0,0 +1,58 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is invoked when evaluation of AssignmentElementList returns
+    a "return" completion and the iterator has not been marked as "done"
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    [...]
+    3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
+    4. Let status be the result of performing
+       IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
+       iteratorRecord as the argument.
+    5. If status is an abrupt completion, then
+       a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+          status).
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    7. If completion.[[type]] is throw, return Completion(completion).
+    8. If innerResult.[[type]] is throw, return Completion(innerResult).
+features: [Symbol.iterator, generators]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var returnCount = 0;
+var unreachable = 0;
+var iterable = {};
+var iterator = {
+  return: function() {
+    returnCount += 1;
+
+    throw new Test262Error();
+  }
+};
+var iter;
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+function* g() {
+  [ {}[yield] , ] = iterable;
+  unreachable += 1;
+}
+
+iter = g();
+iter.next();
+assert.throws(Test262Error, function() {
+  iter.return();
+});
+
+assert.sameValue(returnCount, 1);
+assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-rtrn-close-null.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-rtrn-close-null.js
new file mode 100644
index 0000000000000000000000000000000000000000..c635b1b1304696f45ffb1d198501ee8990a554ed
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-rtrn-close-null.js
@@ -0,0 +1,53 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose throws a TypeError when `return` returns a non-Object value
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    [...]
+    3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
+    4. Let status be the result of performing
+       IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
+       iteratorRecord as the argument.
+    5. If status is an abrupt completion, then
+       a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+          status).
+       b. Return Completion(status).
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    7. If completion.[[type]] is throw, return Completion(completion).
+    8. If innerResult.[[type]] is throw, return Completion(innerResult).
+    9. If Type(innerResult.[[value]]) is not Object, throw a TypeError
+       exception.
+features: [Symbol.iterator, generators]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var iterable = {};
+var iterator = {
+  return: function() {
+    return null;
+  }
+};
+var iter;
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+function* g() {
+  [ {}[yield] , ] = iterable;
+}
+
+iter = g();
+iter.next();
+
+assert.throws(TypeError, function() {
+  iter.return();
+});
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-rtrn-close.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-rtrn-close.js
new file mode 100644
index 0000000000000000000000000000000000000000..076dfeaccaadd012318668dce6a97e5160458b68
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-rtrn-close.js
@@ -0,0 +1,66 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is invoked when evaluation of AssignmentElementList returns
+    a "return" completion and the iterator has not been marked as "done"
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    [...]
+    3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
+    4. Let status be the result of performing
+       IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
+       iteratorRecord as the argument.
+    5. If status is an abrupt completion, then
+       a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+          status).
+       b. Return Completion(status).
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    7. If completion.[[type]] is throw, return Completion(completion).
+    8. If innerResult.[[type]] is throw, return Completion(innerResult).
+features: [Symbol.iterator, generators]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var returnCount = 0;
+var unreachable = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var iterator = {
+  return: function() {
+    returnCount += 1;
+    thisValue = this;
+    args = arguments;
+    return {};
+  }
+};
+var iter, result;
+
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+function* g() {
+  [ {}[yield] , ] = iterable;
+  unreachable += 1;
+};
+
+iter = g();
+iter.next();
+result = iter.return(888);
+
+assert.sameValue(returnCount, 1);
+assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
+assert.sameValue(result.value, 888);
+assert(result.done, 'Iterator correctly closed');
+assert.sameValue(thisValue, iterator, 'correct `this` value');
+assert(!!args, 'arguments object provided');
+assert.sameValue(args.length, 0, 'zero arguments specified');
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-thrw-close-err.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-thrw-close-err.js
new file mode 100644
index 0000000000000000000000000000000000000000..6580d3f941ff504d1d4402c97bc36a95b46db845
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-thrw-close-err.js
@@ -0,0 +1,58 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is invoked when evaluation of AssignmentElementList returns
+    a "throw" completion and the iterator has not been marked as "done"
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    [...]
+    3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
+    4. Let status be the result of performing
+       IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
+       iteratorRecord as the argument.
+    5. If status is an abrupt completion, then
+       a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+          status).
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    7. If completion.[[type]] is throw, return Completion(completion).
+
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var thrower = function() {
+  throw new Test262Error();
+};
+function ReturnError() {}
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    return { done: true };
+  },
+  return: function() {
+    returnCount += 1;
+
+    // This value should be discarded.
+    throw new ReturnError();
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(Test262Error, function() {
+  [ {}[thrower()] , ] = iterable;
+});
+
+assert.sameValue(nextCount, 0);
+assert.sameValue(returnCount, 1);
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-thrw-close-skip.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-thrw-close-skip.js
new file mode 100644
index 0000000000000000000000000000000000000000..f07335161db882dc2d806908509e68ad1d5fa780
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-thrw-close-skip.js
@@ -0,0 +1,50 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is not invoked when evaluation of AssignmentElementList
+    returns an abrupt completion and the iterator has been marked as "done"
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    [...]
+    3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
+    4. Let status be the result of performing
+       IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
+       iteratorRecord as the argument.
+    5. If status is an abrupt completion, then
+       a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+          status).
+       b. Return Completion(status).
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var thrower = function() {
+  throw new Test262Error();
+};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    throw new Test262Error();
+  },
+  return: function() {
+    returnCount += 1;
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+var x;
+
+assert.throws(Test262Error, function() {
+  [ x , ] = iterable;
+});
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-thrw-close.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-thrw-close.js
new file mode 100644
index 0000000000000000000000000000000000000000..d0b18b6d9df53a352da7403a64974d8f4f714143
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-list-thrw-close.js
@@ -0,0 +1,62 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is invoked when evaluation of AssignmentElementList returns
+    a "throw" completion and the iterator has not been marked as "done"
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    [...]
+    3. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
+    4. Let status be the result of performing
+       IteratorDestructuringAssignmentEvaluation of AssignmentElementList using
+       iteratorRecord as the argument.
+    5. If status is an abrupt completion, then
+       a. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+          status).
+       b. Return Completion(status).
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    [...]
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var thrower = function() {
+  throw new Test262Error();
+};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    return { done: true };
+  },
+  return: function() {
+    returnCount += 1;
+    thisValue = this;
+    args = arguments;
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(Test262Error, function() {
+  [ {}[thrower()] , ] = iterable;
+});
+
+assert.sameValue(nextCount, 0);
+assert.sameValue(returnCount, 1);
+assert.sameValue(thisValue, iterator, 'correct `this` value');
+assert(!!args, 'arguments object provided');
+assert.sameValue(args.length, 0, 'zero arguments specified');
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-rest-nrml-close-skip.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-rest-nrml-close-skip.js
new file mode 100644
index 0000000000000000000000000000000000000000..4f4cf16281dad1038844a9d010bfc5483a8ff633
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-rest-nrml-close-skip.js
@@ -0,0 +1,46 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is not called when rest element evaluation has exhausted the
+    iterator
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    [...]
+    7. If AssignmentRestElement is present, then
+       a. Let status be the result of performing
+          IteratorDestructuringAssignmentEvaluation of AssignmentRestElement
+          with iteratorRecord as the argument.
+    8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       status).
+    9. Return Completion(status).
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var x, y;
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    return { value: nextCount, done: nextCount > 1 };
+  },
+  return: function() {
+    returnCount += 1;
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+[ x , ...y ] = iterable;
+
+assert.sameValue(nextCount, 2, 'nextCount');
+assert.sameValue(returnCount, 0, 'returnCount');
+assert.sameValue(x, 1, 'x');
+assert.sameValue(y.length, 0, 'y.length');
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-rest-rtrn-close-err.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-rest-rtrn-close-err.js
new file mode 100644
index 0000000000000000000000000000000000000000..ce2189ac37f4aca2bd8915be761f36390499479d
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-rest-rtrn-close-err.js
@@ -0,0 +1,67 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is called when AssignmentRestEvaluation produces a "return"
+    completion due to reference evaluation
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    [...]
+    7. If AssignmentRestElement is present, then
+       a. Let status be the result of performing
+          IteratorDestructuringAssignmentEvaluation of AssignmentRestElement
+          with iteratorRecord as the argument.
+    8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       status).
+    9. Return Completion(status).
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    7. If completion.[[type]] is throw, return Completion(completion).
+    8. If innerResult.[[type]] is throw, return Completion(innerResult).
+features: [Symbol.iterator, generators]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var unreachable = 0;
+var x;
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    // Set an upper-bound to limit unnecessary iteration in non-conformant
+    // implementations
+    return { done: nextCount > 10 };
+  },
+  return: function() {
+    returnCount += 1;
+
+    throw new Test262Error();
+  }
+};
+var iter;
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+function* g() {
+  [ x , ...{}[yield] ] = iterable;
+  unreachable += 1;
+}
+
+iter = g();
+iter.next();
+
+assert.throws(Test262Error, function() {
+  iter.return();
+});
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
+assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-rest-rtrn-close-null.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-rest-rtrn-close-null.js
new file mode 100644
index 0000000000000000000000000000000000000000..f25ec5b79aee23951408bc07c2acb3bbf3391344
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-rest-rtrn-close-null.js
@@ -0,0 +1,60 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose throws a TypeError when `return` returns a non-Object value
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    [...]
+    7. If AssignmentRestElement is present, then
+       a. Let status be the result of performing
+          IteratorDestructuringAssignmentEvaluation of AssignmentRestElement
+          with iteratorRecord as the argument.
+    8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       status).
+    9. Return Completion(status).
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    7. If completion.[[type]] is throw, return Completion(completion).
+    8. If innerResult.[[type]] is throw, return Completion(innerResult).
+features: [Symbol.iterator, generators]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var iterable = {};
+var x;
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    // Set an upper-bound to limit unnecessary iteration in non-conformant
+    // implementations
+    return { done: nextCount > 10 };
+  },
+  return: function() {
+    return null;
+  }
+};
+var iter;
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+function* g() {
+  [ x , ...{}[yield] ] = iterable;
+}
+
+iter = g();
+iter.next();
+
+assert.throws(TypeError, function() {
+  iter.return();
+});
+
+assert.sameValue(nextCount, 1);
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-rest-rtrn-close.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-rest-rtrn-close.js
new file mode 100644
index 0000000000000000000000000000000000000000..da1e805331884c3b21e9c41fda3c6fd35b8dd607
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-rest-rtrn-close.js
@@ -0,0 +1,73 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is called when AssignmentRestEvaluation produces a "return"
+    completion due to reference evaluation
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    [...]
+    7. If AssignmentRestElement is present, then
+       a. Let status be the result of performing
+          IteratorDestructuringAssignmentEvaluation of AssignmentRestElement
+          with iteratorRecord as the argument.
+    8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       status).
+    9. Return Completion(status).
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    7. If completion.[[type]] is throw, return Completion(completion).
+    8. If innerResult.[[type]] is throw, return Completion(innerResult).
+features: [Symbol.iterator, generators]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var unreachable = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var x;
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    // Set an upper-bound to limit unnecessary iteration in non-conformant
+    // implementations
+    return { done: nextCount > 10 };
+  },
+  return: function() {
+    returnCount += 1;
+    thisValue = this;
+    args = arguments;
+    return {};
+  }
+};
+var iter, result;
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+function* g() {
+  [ x , ...{}[yield] ] = iterable;
+  unreachable += 1;
+}
+
+iter = g();
+iter.next();
+result = iter.return(999);
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
+assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
+assert.sameValue(result.value, 999);
+assert(result.done, 'Iterator correctly closed');
+assert.sameValue(thisValue, iterator, 'correct `this` value');
+assert(!!args, 'arguments object provided');
+assert.sameValue(args.length, 0, 'zero arguments specified');
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-rest-thrw-close-err.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-rest-thrw-close-err.js
new file mode 100644
index 0000000000000000000000000000000000000000..beea275ccca5e70d3b003376d8ba82d70925297c
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-rest-thrw-close-err.js
@@ -0,0 +1,60 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is called when AssignmentRestEvaluation produces a "throw"
+    completion due to reference evaluation
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    [...]
+    7. If AssignmentRestElement is present, then
+       a. Let status be the result of performing
+          IteratorDestructuringAssignmentEvaluation of AssignmentRestElement
+          with iteratorRecord as the argument.
+    8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       status).
+    9. Return Completion(status).
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    7. If completion.[[type]] is throw, return Completion(completion)
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var x;
+function ReturnError() {}
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    // Set an upper-bound to limit unnecessary iteration in non-conformant
+    // implementations
+    return { done: nextCount > 10 };
+  },
+  return: function() {
+    returnCount += 1;
+
+    // This value should be discarded.
+    throw new ReturnError();
+  }
+};
+var thrower = function() {
+  throw new Test262Error();
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(Test262Error, function() {
+  [ x , ...{}[thrower()] ] = iterable;
+});
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-rest-thrw-close-skip.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-rest-thrw-close-skip.js
new file mode 100644
index 0000000000000000000000000000000000000000..4619bc0738d1a2b359953bb12eddb9142390bdce
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-rest-thrw-close-skip.js
@@ -0,0 +1,51 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Abrupt completion returned during iteration for rest element
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    [...]
+    7. If AssignmentRestElement is present, then
+       a. Let status be the result of performing
+          IteratorDestructuringAssignmentEvaluation of AssignmentRestElement
+          with iteratorRecord as the argument.
+    8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       status).
+    9. Return Completion(status).
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var x;
+var iterator = {
+  next: function() {
+    nextCount += 1;
+
+    if (nextCount === 2) {
+      throw new Test262Error();
+    }
+
+    // Set an upper-bound to limit unnecessary iteration in non-conformant
+    // implementations
+    return { done: nextCount > 10 };
+  },
+  return: function() {
+    returnCount += 1;
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(Test262Error, function() {
+  [ x , ...x ] = iterable;
+});
+
+assert.sameValue(nextCount, 2);
+assert.sameValue(returnCount, 0);
diff --git a/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-rest-thrw-close.js b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-rest-thrw-close.js
new file mode 100644
index 0000000000000000000000000000000000000000..eefc3e146645dedafd4fcf2bee60b120685a37ef
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elem-trlg-iter-rest-thrw-close.js
@@ -0,0 +1,64 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is called when AssignmentRestEvaluation produces a "throw"
+    completion due to reference evaluation
+info: |
+    ArrayAssignmentPattern :
+        [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
+
+    [...]
+    7. If AssignmentRestElement is present, then
+       a. Let status be the result of performing
+          IteratorDestructuringAssignmentEvaluation of AssignmentRestElement
+          with iteratorRecord as the argument.
+    8. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       status).
+    9. Return Completion(status).
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    [...]
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var x;
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    // Set an upper-bound to limit unnecessary iteration in non-conformant
+    // implementations
+    return { done: nextCount > 10 };
+  },
+  return: function() {
+    returnCount += 1;
+    thisValue = this;
+    args = arguments;
+  }
+};
+var thrower = function() {
+  throw new Test262Error();
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(Test262Error, function() {
+  [ x , ...{}[thrower()] ] = iterable;
+});
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
+assert.sameValue(thisValue, iterator, 'correct `this` value');
+assert(!!args, 'arguments object provided');
+assert.sameValue(args.length, 0, 'zero arguments specified');
diff --git a/test/language/expressions/assignment/destructuring/array-elision-iter-abpt.js b/test/language/expressions/assignment/destructuring/array-elision-iter-abpt.js
new file mode 100644
index 0000000000000000000000000000000000000000..82d43234bc0cc15521ead2c8bb7bed3db55ee932
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elision-iter-abpt.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is not called when iteration produces an abrupt completion
+info: |
+    ArrayAssignmentPattern : [ Elision ]
+
+    1. Let iterator be GetIterator(value).
+    [...]
+    5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+    [...]
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    throw new Test262Error();
+  },
+  return: function() {
+    returnCount += 1;
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(Test262Error, function() {
+  [ , ] = iterable;
+});
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
diff --git a/test/language/expressions/assignment/destructuring/array-elision-iter-get-err.js b/test/language/expressions/assignment/destructuring/array-elision-iter-get-err.js
new file mode 100644
index 0000000000000000000000000000000000000000..8900065f15b6a899aa038fe7e7d7fcd32cdb2447
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elision-iter-get-err.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Abrupt completion returned from GetIterator
+info: |
+    ArrayAssignmentPattern : [ Elision ]
+
+    1. Let iterator be GetIterator(value).
+    2. ReturnIfAbrupt(iterator).
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var iterable = {};
+iterable[Symbol.iterator] = function() {
+  throw new Test262Error();
+};
+
+assert.throws(Test262Error, function() {
+  [ , ] = iterable;
+});
diff --git a/test/language/expressions/assignment/destructuring/array-elision-iter-nrml-close-err.js b/test/language/expressions/assignment/destructuring/array-elision-iter-nrml-close-err.js
new file mode 100644
index 0000000000000000000000000000000000000000..ad5fb2da511b64a4ba90d40b2a8ce88fa0091f57
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elision-iter-nrml-close-err.js
@@ -0,0 +1,43 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    Abrupt completion returned from IteratorClose
+info: |
+    ArrayAssignmentPattern : [ Elision ]
+
+    1. Let iterator be GetIterator(value).
+    [...]
+    5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+    6. Return result.
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    // Set an upper-bound to limit unnecessary iteration in non-conformant
+    // implementations
+    return { done: nextCount > 10 };
+  },
+  return: function() {
+    returnCount += 1;
+    throw new Test262Error();
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(Test262Error, function() {
+  [ , ] = iterable;
+});
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
diff --git a/test/language/expressions/assignment/destructuring/array-elision-iter-nrml-close-null.js b/test/language/expressions/assignment/destructuring/array-elision-iter-nrml-close-null.js
new file mode 100644
index 0000000000000000000000000000000000000000..528c0eaf19a05859b17485256270d426233885f6
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elision-iter-nrml-close-null.js
@@ -0,0 +1,47 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose throws a TypeError when `return` returns a non-Object value
+info: |
+    ArrayAssignmentPattern : [ Elision ]
+
+    1. Let iterator be GetIterator(value).
+    [...]
+    5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+    [...]
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    7. If completion.[[type]] is throw, return Completion(completion).
+    8. If innerResult.[[type]] is throw, return Completion(innerResult).
+    9. If Type(innerResult.[[value]]) is not Object, throw a TypeError
+       exception.
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var iterable = {};
+var nextCount = 0;
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    // Set an upper-bound to limit unnecessary iteration in non-conformant
+    // implementations
+    return { done: nextCount > 10 };
+  },
+  return: function() {
+    return null;
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(TypeError, function() {
+  [ , ] = iterable;
+});
diff --git a/test/language/expressions/assignment/destructuring/array-elision-iter-nrml-close-skip.js b/test/language/expressions/assignment/destructuring/array-elision-iter-nrml-close-skip.js
new file mode 100644
index 0000000000000000000000000000000000000000..ecff8153389d691fb3b85cd34ccdef2bafdf849b
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elision-iter-nrml-close-skip.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is not called when iteration has exhausted the iterator
+info: |
+    ArrayAssignmentPattern : [ Elision ]
+
+    1. Let iterator be GetIterator(value).
+    [...]
+    5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+    [...]
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    return { done: true };
+  },
+  return: function() {
+    returnCount += 1;
+    return {};
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+[ , ] = iterable;
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
diff --git a/test/language/expressions/assignment/destructuring/array-elision-iter-nrml-close.js b/test/language/expressions/assignment/destructuring/array-elision-iter-nrml-close.js
new file mode 100644
index 0000000000000000000000000000000000000000..eba1f3cef4177101b4b3333247cbb8d33ca80f64
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-elision-iter-nrml-close.js
@@ -0,0 +1,55 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is called when assignment evaluation has not exhausted the
+    iterator
+info: |
+    ArrayAssignmentPattern : [ Elision ]
+
+    1. Let iterator be GetIterator(value).
+    [...]
+    5. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+    [...]
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    [...]
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    // Set an upper-bound to limit unnecessary iteration in non-conformant
+    // implementations
+    return { done: nextCount > 10 };
+  },
+  return: function() {
+    returnCount += 1;
+    thisValue = this;
+    args = arguments;
+    return {};
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+[ , ] = iterable;
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 1);
+assert.sameValue(thisValue, iterator, 'correct `this` value');
+assert(!!args, 'arguments object provided');
+assert.sameValue(args.length, 0, 'zero arguments specified');
diff --git a/test/language/expressions/assignment/destructuring/array-sparse.js b/test/language/expressions/assignment/destructuring/array-elision.js
similarity index 83%
rename from test/language/expressions/assignment/destructuring/array-sparse.js
rename to test/language/expressions/assignment/destructuring/array-elision.js
index 0699f8909b1fbeeac5ac259cf4791af710d761fb..8933cb5a147735902ac1805a7ba66111151be17c 100644
--- a/test/language/expressions/assignment/destructuring/array-sparse.js
+++ b/test/language/expressions/assignment/destructuring/array-elision.js
@@ -3,8 +3,8 @@
 
 /*---
 description: >
-    A sparse ArrayAssignmentPattern without an AssignmentElementList requires
-    iterable values and throws for other values.
+    An ArrayAssignmentPattern containing only Elisions requires iterable values
+    and throws for other values.
 es6id: 12.14.5.2
 ---*/
 
diff --git a/test/language/expressions/assignment/destructuring/array-empty-iter-close-err.js b/test/language/expressions/assignment/destructuring/array-empty-iter-close-err.js
new file mode 100644
index 0000000000000000000000000000000000000000..a7e1d225fde16658fb2a54a1512b8f3312176e78
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-empty-iter-close-err.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Abrupt completion returned from IteratorClose
+info: |
+    ArrayAssignmentPattern : [ ]
+
+    1. Let iterator be GetIterator(value).
+    2. ReturnIfAbrupt(iterator).
+    3. Return IteratorClose(iterator, NormalCompletion(empty)).
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    return { done: true };
+  },
+  return: function() {
+    returnCount += 1;
+    throw new Test262Error();
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(Test262Error, function() {
+  [] = iterable;
+});
+
+assert.sameValue(nextCount, 0);
+assert.sameValue(returnCount, 1);
diff --git a/test/language/expressions/assignment/destructuring/array-empty-iter-close-null.js b/test/language/expressions/assignment/destructuring/array-empty-iter-close-null.js
new file mode 100644
index 0000000000000000000000000000000000000000..1ef76906be2dec057d14af5572744f4d6ea981f4
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-empty-iter-close-null.js
@@ -0,0 +1,41 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose throws a TypeError when `return` returns a non-Object value
+info: |
+    ArrayAssignmentPattern : [ ]
+
+    1. Let iterator be GetIterator(value).
+    2. ReturnIfAbrupt(iterator).
+    3. Return IteratorClose(iterator, NormalCompletion(empty)).
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    7. If completion.[[type]] is throw, return Completion(completion).
+    8. If innerResult.[[type]] is throw, return Completion(innerResult).
+    9. If Type(innerResult.[[value]]) is not Object, throw a TypeError
+       exception.
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var iterable = {};
+var iterator = {
+  next: function() {
+    return { done: true };
+  },
+  return: function() {
+    return null;
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(TypeError, function() {
+  [] = iterable;
+});
diff --git a/test/language/expressions/assignment/destructuring/array-empty-iter-close.js b/test/language/expressions/assignment/destructuring/array-empty-iter-close.js
new file mode 100644
index 0000000000000000000000000000000000000000..c9a70d9c9aba42612f42c0cd74af760164cca4df
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-empty-iter-close.js
@@ -0,0 +1,49 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Iterator is closed without iterating
+info: |
+    ArrayAssignmentPattern : [ ]
+
+    1. Let iterator be GetIterator(value).
+    2. ReturnIfAbrupt(iterator).
+    3. Return IteratorClose(iterator, NormalCompletion(empty)).
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    [...]
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    return { done: true };
+  },
+  return: function() {
+    returnCount += 1;
+    thisValue = this;
+    args = arguments;
+    return {};
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+[] = iterable;
+
+assert.sameValue(nextCount, 0);
+assert.sameValue(returnCount, 1);
+assert.sameValue(thisValue, iterator, 'correct `this` value');
+assert(!!args, 'arguments object provided');
+assert.sameValue(args.length, 0, 'zero arguments specified');
diff --git a/test/language/expressions/assignment/destructuring/array-empty-iter-get-err.js b/test/language/expressions/assignment/destructuring/array-empty-iter-get-err.js
new file mode 100644
index 0000000000000000000000000000000000000000..efd5b21d4a4e4896adae9ec2f442392664e46ca1
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-empty-iter-get-err.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Abrupt completion returned from GetIterator
+info: |
+    ArrayAssignmentPattern : [ ]
+
+    1. Let iterator be GetIterator(value).
+    2. ReturnIfAbrupt(iterator).
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var iterable = {};
+iterable[Symbol.iterator] = function() {
+  throw new Test262Error();
+};
+
+assert.throws(Test262Error, function() {
+  [] = iterable;
+});
diff --git a/test/language/expressions/assignment/destructuring/array-rest-elision-iter-abpt.js b/test/language/expressions/assignment/destructuring/array-rest-elision-iter-abpt.js
new file mode 100644
index 0000000000000000000000000000000000000000..367cc892fe7d16eb757d0f0cfac3f306d672d449
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-rest-elision-iter-abpt.js
@@ -0,0 +1,46 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is not called when assignment evaluation produces an abrupt
+    completion
+info: |
+    ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+    [...]
+    4. If Elision is present, then
+       a. Let status be the result of performing
+          IteratorDestructuringAssignmentEvaluation of Elision with
+          iteratorRecord as the argument.
+       b. If status is an abrupt completion, then
+          i. If iteratorRecord.[[done]] is false, return
+             IteratorClose(iterator, status).
+          ii. Return Completion(status).
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    throw new Test262Error();
+  },
+  return: function() {
+    returnCount += 1;
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+var x;
+
+assert.throws(Test262Error, function() {
+  [ , ...x] = iterable;
+});
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
diff --git a/test/language/expressions/assignment/destructuring/array-rest-iter-get-err.js b/test/language/expressions/assignment/destructuring/array-rest-iter-get-err.js
new file mode 100644
index 0000000000000000000000000000000000000000..6cf2f2d45ec5f2d939ec4643403ad0c9ce6e1b1b
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-rest-iter-get-err.js
@@ -0,0 +1,23 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Abrupt completion returned from GetIterator
+info: |
+    ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+    1. Let iterator be GetIterator(value).
+    2. ReturnIfAbrupt(iterator).
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var iterable = {};
+var x;
+iterable[Symbol.iterator] = function() {
+  throw new Test262Error();
+};
+
+assert.throws(Test262Error, function() {
+  [...x] = iterable;
+});
diff --git a/test/language/expressions/assignment/destructuring/array-rest-iter-nrml-close-skip.js b/test/language/expressions/assignment/destructuring/array-rest-iter-nrml-close-skip.js
new file mode 100644
index 0000000000000000000000000000000000000000..5bb22af60b9a42e57fbd74a6e4d15f9cf23a0fe7
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-rest-iter-nrml-close-skip.js
@@ -0,0 +1,42 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is not called when assignment evaluation has exhausted the
+    iterator
+info: |
+    ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+    [...]
+    5. Let result be the result of performing
+       IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
+       iteratorRecord as the argument
+    6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+    7. Return result.
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var x;
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    return { done: true };
+  },
+  return: function() {
+    returnCount += 1;
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+[ ...x ] = iterable;
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
diff --git a/test/language/expressions/assignment/destructuring/array-rest-iter-rtrn-close-err.js b/test/language/expressions/assignment/destructuring/array-rest-iter-rtrn-close-err.js
new file mode 100644
index 0000000000000000000000000000000000000000..b86607956f56e2a72e6e29eb03b5211cddad5452
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-rest-iter-rtrn-close-err.js
@@ -0,0 +1,63 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is called when reference evaluation produces a "return"
+    completion
+info: |
+    ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+    [...]
+    5. Let result be the result of performing
+       IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
+       iteratorRecord as the argument
+    6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+
+    AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
+
+    1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
+       ArrayLiteral, then
+       a. Let lref be the result of evaluating DestructuringAssignmentTarget.
+       b. ReturnIfAbrupt(lref).
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    7. If completion.[[type]] is throw, return Completion(completion).
+    8. If innerResult.[[type]] is throw, return Completion(innerResult).
+features: [Symbol.iterator, generators]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var returnCount = 0;
+var unreachable = 0;
+function ReturnError() {}
+var iterable = {};
+var iterator = {
+  return: function() {
+    returnCount += 1;
+
+    throw new Test262Error();
+  }
+};
+var iter;
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+function* g() {
+  [...{}[yield]] = iterable;
+  unreachable += 1;
+}
+
+iter = g();
+iter.next();
+assert.throws(Test262Error, function() {
+  iter.return();
+});
+
+assert.sameValue(returnCount, 1);
+assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
diff --git a/test/language/expressions/assignment/destructuring/array-rest-iter-rtrn-close-null.js b/test/language/expressions/assignment/destructuring/array-rest-iter-rtrn-close-null.js
new file mode 100644
index 0000000000000000000000000000000000000000..4b37e9f599eecf207f923981bfab3b1b925b8760
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-rest-iter-rtrn-close-null.js
@@ -0,0 +1,60 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose throws a TypeError when `return` returns a non-Object value
+info: |
+    ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+    [...]
+    5. Let result be the result of performing
+       IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
+       iteratorRecord as the argument
+    6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+
+    AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
+
+    1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
+       ArrayLiteral, then
+       a. Let lref be the result of evaluating DestructuringAssignmentTarget.
+       b. ReturnIfAbrupt(lref).
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    [...]
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    7. If completion.[[type]] is throw, return Completion(completion).
+    8. If innerResult.[[type]] is throw, return Completion(innerResult).
+features: [Symbol.iterator, generators]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var iterable = {};
+var iterator = {
+  return: function() {
+    return null;
+  }
+};
+var iter;
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+function* g() {
+  [...{}[yield]] = iterable;
+}
+
+iter = g();
+iter.next();
+
+assert.throws(TypeError, function() {
+  iter.return();
+});
diff --git a/test/language/expressions/assignment/destructuring/array-rest-iter-rtrn-close.js b/test/language/expressions/assignment/destructuring/array-rest-iter-rtrn-close.js
new file mode 100644
index 0000000000000000000000000000000000000000..da30120406d87c28c68692239fb483e311429e8b
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-rest-iter-rtrn-close.js
@@ -0,0 +1,74 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is called when reference evaluation produces a "return"
+    completion
+info: |
+    ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+    [...]
+    5. Let result be the result of performing
+       IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
+       iteratorRecord as the argument
+    6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+
+    AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
+
+    1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
+       ArrayLiteral, then
+       a. Let lref be the result of evaluating DestructuringAssignmentTarget.
+       b. ReturnIfAbrupt(lref).
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    [...]
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    7. If completion.[[type]] is throw, return Completion(completion).
+    8. If innerResult.[[type]] is throw, return Completion(innerResult).
+features: [Symbol.iterator, generators]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var returnCount = 0;
+var unreachable = 0;
+var thisValue = null;
+var args = null;
+var iterable = {};
+var iterator = {
+  return: function() {
+    returnCount += 1;
+    thisValue = this;
+    args = arguments;
+    return {};
+  }
+};
+var iter, result;
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+function* g() {
+  [...{}[yield]] = iterable;
+  unreachable += 1;
+}
+
+iter = g();
+iter.next();
+result = iter.return(444);
+
+assert.sameValue(returnCount, 1);
+assert.sameValue(unreachable, 0, 'Unreachable statement was not executed');
+assert.sameValue(result.value, 444);
+assert(result.done, 'Iterator correctly closed');
+assert.sameValue(thisValue, iterator, 'correct `this` value');
+assert(!!args, 'arguments object provided');
+assert.sameValue(args.length, 0, 'zero arguments specified');
diff --git a/test/language/expressions/assignment/destructuring/array-rest-iter-thrw-close-err.js b/test/language/expressions/assignment/destructuring/array-rest-iter-thrw-close-err.js
new file mode 100644
index 0000000000000000000000000000000000000000..f39a1465234a86cdfabab4a19fd37451198dbb73
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-rest-iter-thrw-close-err.js
@@ -0,0 +1,59 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is called when reference evaluation produces a "throw"
+    completion
+info: |
+    ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+    [...]
+    5. Let result be the result of performing
+       IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
+       iteratorRecord as the argument
+    6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+
+    AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
+
+    1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
+       ArrayLiteral, then
+       a. Let lref be the result of evaluating DestructuringAssignmentTarget.
+       b. ReturnIfAbrupt(lref).
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var x;
+function ReturnError() {}
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    // Set an upper-bound to limit unnecessary iteration in non-conformant
+    // implementations
+    return { done: nextCount > 10 };
+  },
+  return: function() {
+    returnCount += 1;
+
+    // This value should be discarded.
+    throw new ReturnError();
+  }
+};
+var thrower = function() {
+  throw new Test262Error();
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(Test262Error, function() {
+  [...{}[thrower()]] = iterable;
+});
+
+assert.sameValue(nextCount, 0);
+assert.sameValue(returnCount, 1);
diff --git a/test/language/expressions/assignment/destructuring/array-rest-iter-thrw-close-skip.js b/test/language/expressions/assignment/destructuring/array-rest-iter-thrw-close-skip.js
new file mode 100644
index 0000000000000000000000000000000000000000..84a4cac82012793f63013b4cb642527b2184eced
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-rest-iter-thrw-close-skip.js
@@ -0,0 +1,41 @@
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is not called when iteration produces an abrupt completion
+info: |
+    ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+    [...]
+    5. Let result be the result of performing
+       IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
+       iteratorRecord as the argument
+    6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var x;
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    throw new Test262Error();
+  },
+  return: function() {
+    returnCount += 1;
+  }
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(Test262Error, function() {
+  [...x] = iterable;
+});
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
diff --git a/test/language/expressions/assignment/destructuring/array-rest-iter-thrw-close.js b/test/language/expressions/assignment/destructuring/array-rest-iter-thrw-close.js
new file mode 100644
index 0000000000000000000000000000000000000000..8e5b4e634c32a233e62e437c69d31bbbfd3e090f
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-rest-iter-thrw-close.js
@@ -0,0 +1,68 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is called when reference evaluation produces a "throw"
+    completion
+info: |
+    ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+    [...]
+    5. Let result be the result of performing
+       IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
+       iteratorRecord as the argument
+    6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+
+    AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
+
+    1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
+       ArrayLiteral, then
+       a. Let lref be the result of evaluating DestructuringAssignmentTarget.
+       b. ReturnIfAbrupt(lref).
+
+    7.4.6 IteratorClose( iterator, completion )
+
+    [...]
+    6. Let innerResult be Call(return, iterator, « »).
+    [...]
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var thisValue = null;
+var args = null;
+var x;
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    // Set an upper-bound to limit unnecessary iteration in non-conformant
+    // implementations
+    return { done: nextCount > 10 };
+  },
+  return: function() {
+    returnCount += 1;
+    thisValue = this;
+    args = arguments;
+  }
+};
+var thrower = function() {
+  throw new Test262Error();
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(Test262Error, function() {
+  [...{}[thrower()]] = iterable;
+});
+
+assert.sameValue(nextCount, 0);
+assert.sameValue(returnCount, 1);
+assert.sameValue(thisValue, iterator, 'correct `this` value');
+assert(!!args, 'arguments object provided');
+assert.sameValue(args.length, 0, 'zero arguments specified');
diff --git a/test/language/expressions/assignment/destructuring/array-rest-lref-err.js b/test/language/expressions/assignment/destructuring/array-rest-lref-err.js
new file mode 100644
index 0000000000000000000000000000000000000000..2a083bdceeb112a7dc2f50ef03e18900a7e2ee53
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-rest-lref-err.js
@@ -0,0 +1,52 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is called when reference evaluation produces an abrupt
+    completion
+info: |
+    ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+    [...]
+    5. Let result be the result of performing
+       IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
+       iteratorRecord as the argument
+    6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+
+    AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
+
+    1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
+       ArrayLiteral, then
+       a. Let lref be the result of evaluating DestructuringAssignmentTarget.
+       b. ReturnIfAbrupt(lref).
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    return { done: true };
+  },
+  return: function() {
+    returnCount += 1;
+  }
+};
+var thrower = function() {
+  throw new Test262Error();
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(Test262Error, function() {
+  [...{}[thrower()]] = iterable;
+});
+
+assert.sameValue(nextCount, 0);
+assert.sameValue(returnCount, 1);
diff --git a/test/language/expressions/assignment/destructuring/array-rest-lref.js b/test/language/expressions/assignment/destructuring/array-rest-lref.js
new file mode 100644
index 0000000000000000000000000000000000000000..68161c48e8546b2a2963632b8650664089cf3ef5
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-rest-lref.js
@@ -0,0 +1,49 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Reference is evaluated during assignment
+info: |
+    ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+    [...]
+    5. Let result be the result of performing
+       IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
+       iteratorRecord as the argument
+    6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+
+    AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
+
+    1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
+       ArrayLiteral, then
+       a. Let lref be the result of evaluating DestructuringAssignmentTarget.
+       b. ReturnIfAbrupt(lref).
+    [...]
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    return { done: true };
+  },
+  return: function() {
+    returnCount += 1;
+  }
+};
+var obj = {};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+[...obj['a' + 'b']] = iterable;
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
+assert(!!obj.ab);
+assert.sameValue(obj.ab.length, 0);
diff --git a/test/language/expressions/assignment/destructuring/array-rest-nested-array-iter-thrw-close-skip.js b/test/language/expressions/assignment/destructuring/array-rest-nested-array-iter-thrw-close-skip.js
new file mode 100644
index 0000000000000000000000000000000000000000..8d5749624b18b41bfc8a923b30969ceaea0ecf79
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-rest-nested-array-iter-thrw-close-skip.js
@@ -0,0 +1,55 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is not called when nested array pattern evaluation produces
+    an abrupt completion
+info: |
+    ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+    [...]
+    5. Let result be the result of performing
+       IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
+       iteratorRecord as the argument
+    6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+
+    AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
+
+    [...]
+    4. Repeat while iteratorRecord.[[done]] is false
+       [...]
+       d. If next is false, set iteratorRecord.[[done]] to true.
+       [...]
+    7. Return the result of performing DestructuringAssignmentEvaluation of
+       nestedAssignmentPattern with A as the argument.
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    return { done: true };
+  },
+  return: function() {
+    returnCount += 1;
+  }
+};
+var thrower = function() {
+  throw new Test262Error();
+};
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+
+assert.throws(Test262Error, function() {
+  [...[...{}[thrower()]]] = iterable;
+});
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
diff --git a/test/language/expressions/assignment/destructuring/array-rest-put-prop-ref-user-err-iter-close-skip.js b/test/language/expressions/assignment/destructuring/array-rest-put-prop-ref-user-err-iter-close-skip.js
new file mode 100644
index 0000000000000000000000000000000000000000..513f433032c23b54ffabe74be13a633e3944eec3
--- /dev/null
+++ b/test/language/expressions/assignment/destructuring/array-rest-put-prop-ref-user-err-iter-close-skip.js
@@ -0,0 +1,57 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    IteratorClose is not called when value assignment produces an abrupt
+    completion.
+info: |
+    ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
+
+    [...]
+    5. Let result be the result of performing
+       IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with
+       iteratorRecord as the argument
+    6. If iteratorRecord.[[done]] is false, return IteratorClose(iterator,
+       result).
+
+    AssignmentRestElement[Yield] : ... DestructuringAssignmentTarget
+
+    [...]
+    4. Repeat while iteratorRecord.[[done]] is false
+       [...]
+       d. If next is false, set iteratorRecord.[[done]] to true.
+       [...]
+    5. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an
+       ArrayLiteral, then
+       a. Return PutValue(lref, A).
+features: [Symbol.iterator]
+es6id: 12.14.5.2
+esid: sec-runtime-semantics-destructuringassignmentevaluation
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var iterable = {};
+var iterator = {
+  next: function() {
+    nextCount += 1;
+    return { done: true };
+  },
+  return: function() {
+    returnCount += 1;
+  }
+};
+var obj = Object.defineProperty({}, 'poisoned', {
+  set: function(x) {
+    throw new Test262Error();
+  }
+});
+iterable[Symbol.iterator] = function() {
+  return iterator;
+};
+assert.throws(Test262Error, function() {
+  [...obj.poisoned] = iterable;
+});
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);