add type check during eval time (#11475)

# Description
Fixes: #11438 

Take the following as example:
```nushell
def spam [foo: string] {
    $'foo: ($foo | describe)'
}
def outer [--foo: string] {
    spam $foo
}

outer
```
When we call `outer`, type checker only check the all for `outer`, but
doesn't check inside the body of `outer`. This pr is trying to introduce
a type checking process through `Type::is_subtype()` during eval time.

## NOTE
I'm not really sure if it's easy to make a check inside the body of
`outer`. Adding an eval time type checker seems like an easier solution.
As a result: `outer` will be caught by runtime, not parse time type
checker

cc @kubouch 

# User-Facing Changes
After this pr the following call will failed:
```nushell
> outer
Error: nu:🐚:cant_convert

  × Can't convert to string.
   ╭─[entry #27:1:1]
 1 │ def outer [--foo: any] {
 2 │     spam $foo
   ·          ──┬─
   ·            ╰── can't convert nothing to string
 3 │ }
   ╰────
```

# Tests + Formatting
Done

# After Submitting
NaN
This commit is contained in:
WindSoilder
2024-01-12 23:48:53 +08:00
committed by GitHub
parent 8cad12a05c
commit 724818030d
5 changed files with 47 additions and 5 deletions

View File

@@ -214,3 +214,18 @@ fn infinite_recursion_does_not_panic() {
"#);
assert!(actual.err.contains("Recursion limit (50) reached"));
}
#[test]
fn type_check_for_during_eval() -> TestResult {
fail_test(
r#"def spam [foo: string] { $foo | describe }; def outer [--foo: string] { spam $foo }; outer"#,
"can't convert nothing to string",
)
}
#[test]
fn type_check_for_during_eval2() -> TestResult {
fail_test(
r#"def spam [foo: string] { $foo | describe }; def outer [--foo: any] { spam $foo }; outer"#,
"can't convert nothing to string",
)
}

View File

@@ -114,6 +114,14 @@ fn record_subtyping_allows_general_inner() -> TestResult {
)
}
#[test]
fn record_subtyping_works() -> TestResult {
run_test(
r#"def merge_records [other: record<bar: int>] { "" }; merge_records {"bar": 3, "foo": 4}"#,
"",
)
}
#[test]
fn transpose_into_load_env() -> TestResult {
run_test(