From 899d324a9cc4e37806568dcf87a6c69f788eb258 Mon Sep 17 00:00:00 2001 From: ahkrr <44893716+ahkrr@users.noreply.github.com> Date: Tue, 19 Jan 2021 19:21:11 +0100 Subject: [PATCH] fix: error Variable not in scope for a def parameter #2901 (#2951) adding tests to notice regressions on this issue Co-authored-by: hk --- crates/nu-protocol/src/hir.rs | 2 +- tests/shell/pipeline/commands/internal.rs | 70 +++++++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/crates/nu-protocol/src/hir.rs b/crates/nu-protocol/src/hir.rs index 23cc445f4..4912bc3bb 100644 --- a/crates/nu-protocol/src/hir.rs +++ b/crates/nu-protocol/src/hir.rs @@ -1173,7 +1173,7 @@ impl Expression { output.extend(item.get_free_variables(known_variables)); } } - Expression::Invocation(block) => { + Expression::Invocation(block) | Expression::Block(block) => { output.extend(block.get_free_variables(known_variables)); } Expression::Binary(binary) => { diff --git a/tests/shell/pipeline/commands/internal.rs b/tests/shell/pipeline/commands/internal.rs index 3847b61ce..c6168f5a6 100644 --- a/tests/shell/pipeline/commands/internal.rs +++ b/tests/shell/pipeline/commands/internal.rs @@ -810,3 +810,73 @@ mod tilde_expansion { assert_eq!(actual.out, "1~1"); } } + +mod variable_scoping { + use nu_test_support::nu; + + macro_rules! test_variable_scope { + ($func:literal == $res:literal $(,)*) => { + let actual = nu!( + cwd: ".", + $func + ); + + assert_eq!(actual.out, $res); + }; + } + macro_rules! test_variable_scope_list { + ($func:literal == $res:expr $(,)*) => { + let actual = nu!( + cwd: ".", + $func + ); + + let result: Vec<&str> = actual.out.matches("ZZZ").collect(); + assert_eq!(result, $res); + }; + } + + #[test] + fn access_variables_in_scopes() { + test_variable_scope!( + r#" def test [input] { echo [0 1 2] | do { do { echo $input } } } + test ZZZ "# + == "ZZZ" + ); + test_variable_scope!( + r#" def test [input] { echo [0 1 2] | do { do { if $input == "ZZZ" { echo $input } { echo $input } } } } + test ZZZ "# + == "ZZZ" + ); + test_variable_scope!( + r#" def test [input] { echo [0 1 2] | do { do { if $input == "ZZZ" { echo $input } { echo $input } } } } + test ZZZ "# + == "ZZZ" + ); + test_variable_scope!( + r#" def test [input] { echo [0 1 2] | do { echo $input } } + test ZZZ "# + == "ZZZ" + ); + test_variable_scope!( + r#" def test [input] { echo [0 1 2] | do { if $input == $input { echo $input } { echo $input } } } + test ZZZ "# + == "ZZZ" + ); + test_variable_scope_list!( + r#" def test [input] { echo [0 1 2] | each { echo $input } } + test ZZZ "# + == ["ZZZ", "ZZZ", "ZZZ"] + ); + test_variable_scope_list!( + r#" def test [input] { echo [0 1 2] | each { if $it > 0 {echo $input} {echo $input}} } + test ZZZ "# + == ["ZZZ", "ZZZ", "ZZZ"] + ); + test_variable_scope_list!( + r#" def test [input] { echo [0 1 2] | each { if $input == $input {echo $input} {echo $input}} } + test ZZZ "# + == ["ZZZ", "ZZZ", "ZZZ"] + ); + } +}