making empty list matches list<int> types (#11596)

# Description
Fixes: #11595

The original issue is caused by #11475, we also need to make empty list
matches `list type` or `table type`

cc @amtoine 

# User-Facing Changes
Nan

# Tests + Formatting
Done
This commit is contained in:
WindSoilder 2024-01-26 22:24:17 +08:00 committed by GitHub
parent d646903161
commit 56acebb826
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 31 additions and 7 deletions

View File

@ -61,13 +61,25 @@ pub fn eval_call(
if let Some(arg) = call.positional_nth(param_idx) {
let result = eval_expression(engine_state, caller_stack, arg)?;
if required && !result.get_type().is_subtype(&param.shape.to_type()) {
return Err(ShellError::CantConvert {
to_type: param.shape.to_type().to_string(),
from_type: result.get_type().to_string(),
span: result.span(),
help: None,
});
let param_type = param.shape.to_type();
if required && !result.get_type().is_subtype(&param_type) {
// need to check if result is an empty list, and param_type is table or list
// nushell needs to pass type checking for the case.
let empty_list_matches = result
.as_list()
.map(|l| {
l.is_empty() && matches!(param_type, Type::List(_) | Type::Table(_))
})
.unwrap_or(false);
if !empty_list_matches {
return Err(ShellError::CantConvert {
to_type: param.shape.to_type().to_string(),
from_type: result.get_type().to_string(),
span: result.span(),
help: None,
});
}
}
callee_stack.add_var(var_id, result);
} else if let Some(value) = &param.default_value {

View File

@ -229,6 +229,18 @@ fn type_check_for_during_eval2() -> TestResult {
)
}
#[test]
fn empty_list_matches_list_type() -> TestResult {
let _ = run_test(
r#"def spam [foo: list<int>] { echo $foo }; spam [] | length"#,
"0",
);
run_test(
r#"def spam [foo: list<string>] { echo $foo }; spam [] | length"#,
"0",
)
}
#[test]
fn path_argument_dont_auto_expand_if_single_quoted() -> TestResult {
run_test("def spam [foo: path] { echo $foo }; spam '~/aa'", "~/aa")