Repository: babel/babel (TypeScript)

Issue:
[Bug]: Transform block scoping fails with for in statement inside loop
### 💻

- [ ] Would you like to work on a fix?

### How are you using Babel?

Programmatic API (`babel.transform`, `babel.parse`)

### Input code

I was able to replicate this issue in babeljs.io with the following code:

```js
function w() {
    for (let i = 0; i < y; i++) {
        let outer = {}
        for (var key in someObj) {
            let x = () => outer;
        }
    }
}
```

### Configuration file name

_No response_

### Configuration

Using the transform-block-scoping plugin only.

### Current and expected behavior

Expected Babel to be able to parse & transform the code without throwing any exceptions.

Actual behavior is an error:
```
/repl.js: Property left of ForInStatement expected node to be of a type ["VariableDeclaration","LVal"] but instead got undefined
```

### Environment

I could replicate this issue in babeljs.io

### Possible solution

_No response_

### Additional context

_No response_


Hints:
Hey @luiscubal! 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](https://babeljs.slack.com) that typically always has someone willing to help. You can sign-up [here](https://slack.babeljs.io/) for an invite.

Patch:
diff --git a/packages/babel-plugin-transform-block-scoping/src/loop.ts b/packages/babel-plugin-transform-block-scoping/src/loop.ts
--- a/packages/babel-plugin-transform-block-scoping/src/loop.ts
+++ b/packages/babel-plugin-transform-block-scoping/src/loop.ts
@@ -239,17 +239,13 @@ export function wrapLoopBody(
       varNames.push(...Object.keys(t.getBindingIdentifiers(decl.id)));
       if (decl.init) {
         assign.push(t.assignmentExpression("=", decl.id, decl.init));
+      } else if (t.isForXStatement(varPath.parent, { left: varPath.node })) {
+        assign.push(decl.id as t.Identifier);
       }
     }
     if (assign.length > 0) {
-      let replacement: t.Node =
+      const replacement: t.Node =
         assign.length === 1 ? assign[0] : t.sequenceExpression(assign);
-      if (
-        !t.isForStatement(varPath.parent, { init: varPath.node }) &&
-        !t.isForXStatement(varPath.parent, { left: varPath.node })
-      ) {
-        replacement = t.expressionStatement(replacement);
-      }
       varPath.replaceWith(replacement);
     } else {
       varPath.remove();


Test patch:
diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/for-inside-for-x/input.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/for-inside-for-x/input.js
new file mode 100644
--- /dev/null
+++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/for-inside-for-x/input.js
@@ -0,0 +1,17 @@
+function w() {
+    for (let i = 0; i < y; i++) {
+        let outer = {}
+        for (var key in someObj) {
+            let x = () => outer;
+        }
+    }
+}
+
+function w2() {
+    for (let i = 0; i < y; i++) {
+        let outer = {}
+        for (var key of someObj) {
+            let x = () => outer;
+        }
+    }
+}
diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/for-inside-for-x/output.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/for-inside-for-x/output.js
new file mode 100644
--- /dev/null
+++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/for-inside-for-x/output.js
@@ -0,0 +1,28 @@
+function w() {
+  var _loop = function () {
+      var outer = {};
+      for (key in someObj) {
+        var x = function () {
+          return outer;
+        };
+      }
+    },
+    key;
+  for (var i = 0; i < y; i++) {
+    _loop();
+  }
+}
+function w2() {
+  var _loop2 = function () {
+      var outer = {};
+      for (key of someObj) {
+        var x = function () {
+          return outer;
+        };
+      }
+    },
+    key;
+  for (var i = 0; i < y; i++) {
+    _loop2();
+  }
+}
diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/for-x-inside-for/input.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/for-x-inside-for/input.js
new file mode 100644
--- /dev/null
+++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/for-x-inside-for/input.js
@@ -0,0 +1,8 @@
+function w() {
+  for (let key in someObj) {
+    let outer = {}
+    for (var i = 0; i < y; i++) {
+      let x = () => outer;
+    }
+  }
+}
diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/for-x-inside-for/output.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/for-x-inside-for/output.js
new file mode 100644
--- /dev/null
+++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/for-x-inside-for/output.js
@@ -0,0 +1,14 @@
+function w() {
+  var _loop = function () {
+      var outer = {};
+      for (i = 0; i < y; i++) {
+        var x = function () {
+          return outer;
+        };
+      }
+    },
+    i;
+  for (var key in someObj) {
+    _loop();
+  }
+}