IR: Don't generate instructions for def and export def. (#14114)

# Description
Fixes: #14110
Fixes: #14087

I think it's ok to not generating instruction to `def` and `export def`
call. Because they just return `PipelineData::Empty` without doing
anything.

If nushell generates instructions for `def` and `export def`, nushell
will try to capture variables for these block. It's not the time to do
this.

# User-Facing Changes
```
nu -c "
def bar [] {
    let x = 1
    ($x | foo)
}
def foo [] {
    foo
}
" 
```
Will no longer raise error.

# Tests + Formatting
Added 4 tests
This commit is contained in:
Wind 2024-11-07 13:35:00 +08:00 committed by GitHub
parent b6eda33438
commit b7af715f6b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 37 additions and 0 deletions

View File

@ -292,3 +292,37 @@ fn def_env_wrapped_no_help() {
let actual = nu!("def --wrapped foo [...rest] { echo $rest }; foo -h | to json --raw"); let actual = nu!("def --wrapped foo [...rest] { echo $rest }; foo -h | to json --raw");
assert_eq!(actual.out, r#"["-h"]"#); assert_eq!(actual.out, r#"["-h"]"#);
} }
#[test]
fn def_recursive_func_should_work() {
let actual = nu!("def bar [] { let x = 1; ($x | foo) }; def foo [] { foo }");
assert!(actual.err.is_empty());
let actual = nu!(r#"
def recursive [c: int] {
if ($c == 0) { return }
if ($c mod 2 > 0) {
$in | recursive ($c - 1)
} else {
recursive ($c - 1)
}
}"#);
assert!(actual.err.is_empty());
}
#[test]
fn export_def_recursive_func_should_work() {
let actual = nu!("export def bar [] { let x = 1; ($x | foo) }; export def foo [] { foo }");
assert!(actual.err.is_empty());
let actual = nu!(r#"
export def recursive [c: int] {
if ($c == 0) { return }
if ($c mod 2 > 0) {
$in | recursive ($c - 1)
} else {
recursive ($c - 1)
}
}"#);
assert!(actual.err.is_empty());
}

View File

@ -71,6 +71,9 @@ pub(crate) fn compile_call(
"return" => { "return" => {
return compile_return(working_set, builder, call, redirect_modes, io_reg); return compile_return(working_set, builder, call, redirect_modes, io_reg);
} }
"def" | "export def" => {
return builder.load_empty(io_reg);
}
_ => (), _ => (),
} }
} }