Skip to content

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

Closed
@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

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions