New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong behaviour in "for...of" statement #8839

Open
macabeus opened this Issue Oct 11, 2018 · 5 comments

Comments

Projects
None yet
4 participants
@macabeus
Contributor

macabeus commented Oct 11, 2018

Bug Report

Current Behavior
Throws this exception:

TypeError: undefined: Duplicate declaration "i"
  1 | 
  2 | for (let i of 'foo') {
> 3 |   let i = 'a';
    |       ^
  4 |   console.log(i);
  5 | }
  6 | 

Input Code

for (let i of 'foo') {
  let i = 'a';
  console.log(i);
}

Expected behavior/code
Should prints 'a' three times instead of throws this exception.
This is the behaviour in Node and Safari, for example.

Babel Configuration (CLI command)

const output = require('@babel/core').transform(`
for (let i of 'foo') {
  let i = 'a';
  console.log(i);
}
`, {
  presets: ['@babel/preset-env']
});

Environment

  • Babel version(s): lastest
  • Node/npm version: Node 9
  • OS: macOS High Sierra
  • Monorepo: yes
  • How you are using Babel: cli
@babel-bot

This comment has been minimized.

Show comment
Hide comment
@babel-bot

babel-bot Oct 11, 2018

Collaborator

Hey @macabeus! We really appreciate you taking the time to report an issue. The collaborators
on this project attempt to help as many people as possible, but we're a limited number of volunteers,
so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack
community that typically always has someone willing to help. You can sign-up here
for an invite.

Collaborator

babel-bot commented Oct 11, 2018

Hey @macabeus! We really appreciate you taking the time to report an issue. The collaborators
on this project attempt to help as many people as possible, but we're a limited number of volunteers,
so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack
community that typically always has someone willing to help. You can sign-up here
for an invite.

@ghost

This comment has been minimized.

Show comment
Hide comment
@ghost

ghost Oct 11, 2018

This error have no connection with for...of. At least I think it's expected behaviour. So you can remove let from second line.

ghost commented Oct 11, 2018

This error have no connection with for...of. At least I think it's expected behaviour. So you can remove let from second line.

@nicolo-ribaudo

This comment has been minimized.

Show comment
Hide comment
@nicolo-ribaudo

nicolo-ribaudo Oct 11, 2018

Member

It's a bug, similar to #8498

Member

nicolo-ribaudo commented Oct 11, 2018

It's a bug, similar to #8498

@macabeus

This comment has been minimized.

Show comment
Hide comment
@macabeus

macabeus Oct 11, 2018

Contributor

@krovc As far as I know, this is not the expected behaviour, because you can shadowing in block of for the variables declared inside of for ... of.

@nicolo-ribaudo Yeah, I found this new bug when I was trying to resolve this another issue, but I could not resolve 😞

Do you have any idea how to resolve it? I'm not sure, but I think that this bug happens because this line not to extend correctly when it have two variables with the same name, or because this function should also to add declarations at node.init if the node is a ForStatement and make more changes at function updateScopeInfo.

Contributor

macabeus commented Oct 11, 2018

@krovc As far as I know, this is not the expected behaviour, because you can shadowing in block of for the variables declared inside of for ... of.

@nicolo-ribaudo Yeah, I found this new bug when I was trying to resolve this another issue, but I could not resolve 😞

Do you have any idea how to resolve it? I'm not sure, but I think that this bug happens because this line not to extend correctly when it have two variables with the same name, or because this function should also to add declarations at node.init if the node is a ForStatement and make more changes at function updateScopeInfo.

@byronluk

This comment has been minimized.

Show comment
Hide comment
@byronluk

byronluk Oct 14, 2018

Contributor

So it seems like TypeError that you're running into is coming from this line.
@babel/core.transform will callbabel-traverse and babel-traverse will call checkBlockScopedCollisions, which is throwing that exception. Seems like it's intentional if there is a function that's explicitly throwing that error... but I'm not entirely sure.

If you comment out these lines in babel-traverse, the initial transform call will run as expected and
output the code below ⬇️ which gives me the expected behavior when I run it in the console.

"use strict";

var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;

try {
  for (var _iterator = 'foo'[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
    var i = _step.value;
    var i = 'a';
    console.log(i);
  }
} catch (err) {
  _didIteratorError = true;
  _iteratorError = err;
} finally {
  try {
    if (!_iteratorNormalCompletion && _iterator.return != null) {
      _iterator.return();
    }
  } finally {
    if (_didIteratorError) {
      throw _iteratorError;
    }
  }
}

Hope that helps! 😬

Contributor

byronluk commented Oct 14, 2018

So it seems like TypeError that you're running into is coming from this line.
@babel/core.transform will callbabel-traverse and babel-traverse will call checkBlockScopedCollisions, which is throwing that exception. Seems like it's intentional if there is a function that's explicitly throwing that error... but I'm not entirely sure.

If you comment out these lines in babel-traverse, the initial transform call will run as expected and
output the code below ⬇️ which gives me the expected behavior when I run it in the console.

"use strict";

var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;

try {
  for (var _iterator = 'foo'[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
    var i = _step.value;
    var i = 'a';
    console.log(i);
  }
} catch (err) {
  _didIteratorError = true;
  _iteratorError = err;
} finally {
  try {
    if (!_iteratorNormalCompletion && _iterator.return != null) {
      _iterator.return();
    }
  } finally {
    if (_didIteratorError) {
      throw _iteratorError;
    }
  }
}

Hope that helps! 😬

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment