mirror of
https://github.com/nushell/nushell.git
synced 2025-08-17 01:01:54 +02:00
Fix parse-time pipeline type checking to support multiple output types for same input type (#16111)
# Description Fixes #15485 This PR changes pipeline checking to keep track of all possible output types instead of only first type matching input type which appears in the input/output types. For example, in this command: ```nushell def foo []: [int -> string, int -> record] { # ... } ``` An `int` input to the command may result in a string or a record to be output. Before this PR, Nushell would always assume that an `int` input would cause a `string` output because it's the first matching input/output type pair. This would cause issues during type checking where the parser would incorrectly determine the output type. After this PR, Nushell considers the command to output either a string or a record. # User-Facing Changes * Parse-time pipeline type checking now properly supports commands with multiple pipeline output types for the same pipeline input type # Tests + Formatting Added a couple tests # After Submitting N/A --------- Co-authored-by: Bahex <Bahex@users.noreply.github.com>
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
use crate::repl::tests::{TestResult, fail_test, run_test};
|
||||
use crate::repl::tests::{TestResult, fail_test, run_test, run_test_contains};
|
||||
use rstest::rstest;
|
||||
|
||||
#[test]
|
||||
@ -178,3 +178,62 @@ fn in_oneof_block_expected_type(#[case] input: &str) -> TestResult {
|
||||
fn in_oneof_block_expected_block() -> TestResult {
|
||||
fail_test("match 1 { 0 => { try 3 } }", "expected block")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pipeline_multiple_types() -> TestResult {
|
||||
// https://github.com/nushell/nushell/issues/15485
|
||||
run_test_contains("{year: 2019} | into datetime | date humanize", "years ago")
|
||||
}
|
||||
|
||||
const MULTIPLE_TYPES_DEFS: &str = "
|
||||
def foo []: [int -> int, int -> string] {
|
||||
if $in > 2 { 'hi' } else 4
|
||||
}
|
||||
def bar []: [int -> filesize, string -> string] {
|
||||
if $in == 'hi' { 'meow' } else { into filesize }
|
||||
}
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn pipeline_multiple_types_custom() -> TestResult {
|
||||
run_test(
|
||||
&format!(
|
||||
"{MULTIPLE_TYPES_DEFS}
|
||||
5 | foo | str trim"
|
||||
),
|
||||
"hi",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pipeline_multiple_types_propagate_string() -> TestResult {
|
||||
run_test(
|
||||
&format!(
|
||||
"{MULTIPLE_TYPES_DEFS}
|
||||
5 | foo | bar | str trim"
|
||||
),
|
||||
"meow",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pipeline_multiple_types_propagate_int() -> TestResult {
|
||||
run_test(
|
||||
&format!(
|
||||
"{MULTIPLE_TYPES_DEFS}
|
||||
2 | foo | bar | format filesize B"
|
||||
),
|
||||
"4 B",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pipeline_multiple_types_propagate_error() -> TestResult {
|
||||
fail_test(
|
||||
&format!(
|
||||
"{MULTIPLE_TYPES_DEFS}
|
||||
2 | foo | bar | values"
|
||||
),
|
||||
"parser::input_type_mismatch",
|
||||
)
|
||||
}
|
||||
|
Reference in New Issue
Block a user