Repository: nushell/nushell (Rust)

Issue:
`it` is somehow a special variable in closure (since 0.92)
### Describe the bug

See more info in discussion link.

#### Discussed in https://github.com/nushell/nushell/discussions/12440

<div type='discussions-op-text'>

<sup>Originally posted by **wdv4758h** April  7, 2024</sup>
With 0.92, it seems that `it` is treated differently.

This print 42 in 0.91, but gets error in 0.92.

```nu
let tmp = {
  let it = 42
  print $it
}

do -c $tmp
```

errors in 0.92:

```sh
  × Missing parameter: $it.
   ╭─[example.nu:6:1]
 5 │ 
 6 │ do -c $tmp
   · ─┬
   ·  ╰── missing parameter: $it
   ╰────
```

This print 42 in both 0.91 and 0.92.

```nu
let tmp = {
  let x = 42
  print $x
}

do -c $tmp
```

### How to reproduce

See above code.

### Expected behavior

Works without error.

### Screenshots

_No response_

### Configuration

| key                | value                                                                           |
| ------------------ | ------------------------------------------------------------------------------- |
| version            | 0.92.3                                                                          |
| major              | 0                                                                               |
| minor              | 92                                                                              |
| patch              | 3                                                                               |
| branch             | nightly                                                                         |
| commit_hash        | 24ecb84d971bf145e31bfab7615028984b4af803                                        |
| build_os           | linux-x86_64                                                                    |
| build_target       | x86_64-unknown-linux-gnu                                                        |
| rust_version       | rustc 1.77.2 (25ef9e3d8 2024-04-09)                                             |
| rust_channel       | 1.77.2-x86_64-unknown-linux-gnu                                                 |
| cargo_version      | cargo 1.77.2 (e52e36006 2024-03-26)                                             |
| build_time         | 2024-04-28 01:44:34 +00:00                                                      |
| build_rust_channel | release                                                                         |
| allocator          | mimalloc                                                                        |
| features           | dataframe, default, sqlite, static-link-openssl, system-clipboard, trash, which |
| installed_plugins  | query                                                                           |

### Additional context

_No response_


Discussion: In `do_.rs` in the `nu-cmd-lang` crate, we get a reference to the `do` block with the following line (l. 78 I think):

```rust
let block = engine_state.get_block(block.block_id);
```

With a debug print, we see that somehow, the block has a positional argument in its signature when `$it` is declared and referenced inside. If I add a positional parameter like so
```nushell
do {|x| print $x; let $it = 2; print $it} 5
```
it works as expected (it prints 5, then 2) and the block only has one positional argument `x`

This behavior seems to come  `parser.rs:4451` in `nu-parser`. If a signature already exists (like the `|x|` above), it takes it, but if not, it creates one if `$it` is in the block, not sure why. Could we get rid of the `else` block there?



@dedebenui Excellent hack!  I think nushell once allowed such syntax before(yeah version 0.44):
```nushell
let x = { echo $it };
```
In this way we need to run `do $x` with additional argument.  But it's not allowed anymore, so I think we can get rid of `else` block there.



Fix (patch):
diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs
index 0f72132d1022c..8514d30877661 100644
--- a/crates/nu-parser/src/parser.rs
+++ b/crates/nu-parser/src/parser.rs
@@ -4177,20 +4177,6 @@ pub fn parse_block_expression(working_set: &mut StateWorkingSet, span: Span) ->
 
     if let Some(signature) = signature {
         output.signature = signature.0;
-    } else if let Some(last) = working_set.delta.scope.last() {
-        // FIXME: this only supports the top $it. Is this sufficient?
-
-        if let Some(var_id) = last.get_var(b"$it") {
-            let mut signature = Signature::new("");
-            signature.required_positional.push(PositionalArg {
-                var_id: Some(*var_id),
-                name: "$it".into(),
-                desc: String::new(),
-                shape: SyntaxShape::Any,
-                default_value: None,
-            });
-            output.signature = Box::new(signature);
-        }
     }
 
     output.span = Some(span);
@@ -4518,20 +4504,6 @@ pub fn parse_closure_expression(
 
     if let Some(signature) = signature {
         output.signature = signature.0;
-    } else if let Some(last) = working_set.delta.scope.last() {
-        // FIXME: this only supports the top $it. Is this sufficient?
-
-        if let Some(var_id) = last.get_var(b"$it") {
-            let mut signature = Signature::new("");
-            signature.required_positional.push(PositionalArg {
-                var_id: Some(*var_id),
-                name: "$it".into(),
-                desc: String::new(),
-                shape: SyntaxShape::Any,
-                default_value: None,
-            });
-            output.signature = Box::new(signature);
-        }
     }
 
     output.span = Some(span);