Skip to content

error when a closure is used as def body #14311

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

Closed

Conversation

sgvictorino
Copy link
Contributor

Closes #9737

User-Facing Changes

def now errors instead of silently ignoring closure blocks:

> def foo [] {|bar| }
Error: nu::parser::parse_mismatch

  × Parse mismatch during operation.
   ╭─[entry #1:1:12]
 1  def foo [] {|bar| }
   ·            ────┬───
   ·                ╰── expected definition body { ... }
   ╰────

@sgvictorino sgvictorino force-pushed the error-on-def-with-closure branch from 56beb98 to 53c997c Compare November 11, 2024 22:37
@WindSoilder
Copy link
Contributor

Sorry, this change will break the following code:

mut x = 3
def a [] {
    $x = 4
}

It should raise error.

@sholderbach
Copy link
Member

Sorry, this change will break the following code:

mut x = 3
def a [] {
    $x = 4
}

It should raise error.

Ah we definitely need a test for those scoping/mutability rules

@sgvictorino sgvictorino marked this pull request as draft November 12, 2024 16:36
@sgvictorino sgvictorino force-pushed the error-on-def-with-closure branch from 53c997c to d81048f Compare November 12, 2024 18:55
@sgvictorino sgvictorino marked this pull request as ready for review November 12, 2024 18:58
@sgvictorino
Copy link
Contributor Author

@WindSoilder good catch! I added a boolean field to SyntaxShape::Block that makes it parse into an Expr::Closure. Hopefully that's alright?

sholderbach added a commit that referenced this pull request Nov 14, 2024
…le (#14314)

@sholderbach suggested that we need to have a test for a function can't
use mutable variable.

#14311 (comment)

So this pr is going to add a case for it.

---------

Co-authored-by: Stefan Holderbach <[email protected]>
@sgvictorino sgvictorino force-pushed the error-on-def-with-closure branch from d81048f to 98f1309 Compare November 14, 2024 16:42
@WindSoilder
Copy link
Contributor

WindSoilder commented Nov 17, 2024

Thanks! I think I get the idea behind these changes, but TBH I'm not sure if the solution is good. It seems too hacky.
Please give me some time to think about this :)

@WindSoilder
Copy link
Contributor

WindSoilder commented Nov 17, 2024

I also found it randomly break my script:

export def main [word: string] {
    if true {
        return "aa"
    } else {
        # query from web
        try {
            let result = http get $"http://url" -m 4 | str length
            $result
        } catch {|e|
            if true {
                let spell_check = "a"
                $spell_check
            } else {
                error make ($e | get raw)
            }
        }
    }
}

It gives me the following error:

Error: nu::parser::parse_mismatch_with_full_string_msg

  × Parse mismatch during operation.
    ╭─[entry #47:4:12]
  3 │             return "aa"
  4 │ ╭─▶     } else {
  5 │ │           # query from web
  6 │ │           try {
  7 │ │               let result = http get $"http://url" -m 4 | str length
  8 │ │               $result
  9 │ │           } catch {|e|
 10 │ │               if true {
 11 │ │                   let spell_check = "a"
 12 │ │                   $spell_check
 13 │ │               } else {
 14 │ │                   error make ($e | get raw)
 15 │ │               }
 16 │ │           }
 17 │ ├─▶     }
    · ╰──── expected one of a list of accepted shapes: [Block(true), Expression]
 18 │     }
    ╰────

@sgvictorino
Copy link
Contributor Author

sgvictorino commented Nov 17, 2024

Update: @WindSoilder that error should be fixed by #14420


That parse error seems to start with the max-time type change (d289c77). I'll work on parse_multispan_value's OneOf handling to try and fix this (reproducible on main):

if true { http get "" -m 4 } else { } # expected duration with valid units
if true { } else { http get "" -m 4 } # expected one of a list of accepted shapes: [Block, Expression]

@sgvictorino
Copy link
Contributor Author

TBH I'm not sure if the solution is good. It seems too hacky. Please give me some time to think about this :)

It's also a breaking change for plugins. That alone might call for a different approach.

@sgvictorino sgvictorino force-pushed the error-on-def-with-closure branch from 98f1309 to d437ff9 Compare November 24, 2024 03:24
@fdncred
Copy link
Contributor

fdncred commented Dec 10, 2024

where are we at on this?

@fdncred fdncred marked this pull request as draft December 10, 2024 12:31
# User-Facing Changes

`def` now errors instead of silently ignoring closure blocks:

```nushell
> def foo [] {|bar| }
Error: nu::parser::parse_mismatch

  × Parse mismatch during operation.
   ╭─[entry nushell#1:1:12]
 1 │ def foo [] {|bar| }
   ·            ────┬───
   ·                ╰── expected definition body { ... }
   ╰────
```
@sgvictorino
Copy link
Contributor Author

sgvictorino commented Dec 10, 2024

I'll fix the conflict but don't know of a cleaner way to solve this without Block(bool) or a new SyntaxShape variant for blocks that can't capture mutable variables.

@sgvictorino sgvictorino force-pushed the error-on-def-with-closure branch from d437ff9 to f844a3d Compare December 10, 2024 18:27
@WindSoilder
Copy link
Contributor

To be honest I still don't think it's the right way to go. Hopefully we can solve it in the new parser.
So I'd like to close the pr and leave that issue open.

@sgvictorino sgvictorino deleted the error-on-def-with-closure branch February 7, 2025 18:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

def allows closures in block
4 participants