Skip to content

Wrong ES3/ES5 code when iterated identifier is reassigned in a 'for...of' statement #5475

@olydis

Description

@olydis

There is an inconsistency regarding the emitted ES3/ES5 code:

var x = [3, 3, 3];
for (var i of x)
{
    x = [2, 2];
    console.log(i);
}

compiles to

var x = [3, 3, 3];
for (var _i = 0; _i < x.length; _i++) {
    var i = x[_i];
    x = [2, 2];
    console.log(i);
}

printing

3
2

instead of (ES6 semantics)

3
3
3

(Note that the code emitted also differs from the feature description: #2207 (comment))


On the other hand, merely adding parentheses around the expression:

var x = [3, 3, 3];
for (var i of (x))
{
    x = [2, 2];
    console.log(i);
}

correctly compiles to

var x = [3, 3, 3];
for (var _a = 0, _b = (x); _a < _b.length; _a++) {
    var i = _b[_a];
    x = [2, 2];
    console.log(i);
}

giving the expected output.


In other words, it looks like there is some sort of faulty optimization applied: As soon as the expression to iterate over is a bare variable, it is not rescued to a new local (here: _b). As shown, this results in wrong semantics.

Metadata

Metadata

Labels

BugA bug in TypeScriptFixedA PR has been merged for this issue

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions