mirror of
https://github.com/nushell/nushell
synced 2024-12-28 14:03:09 +00:00
don't overrite arg's type if it's annotated explicitly (#10424)
# Description Fixes: #10410 So the following script is possible: ```nushell def a [b: any = null] { let b = ($b | default "default_b"); } a "given_b" ``` ## About the change When parsing signature, and nushell meets something like `a: any`, it force the parser to treat `a` as `any` type. This is what `arg_explicit_type` means, it's only set when we goes into `ParseMode::TypeMode`, and it will be reset to `false` if the token goes to next argument. so, when we have something like this: `def a [b: any = null] { $b }`, the type of `$b` won't be overwritten. But if we have something like this: `def a [b = null] { $b }`, the type of `$b` is not annotated, so we make it to be `nothing`(which is the type of null)
This commit is contained in:
parent
989a14709c
commit
bf40f035f6
2 changed files with 35 additions and 8 deletions
|
@ -164,3 +164,19 @@ fn extern_with_block() {
|
||||||
|
|
||||||
assert_eq!(actual.out, "--bar,baz,--,-q,-u,-x");
|
assert_eq!(actual.out, "--bar,baz,--,-q,-u,-x");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn def_default_value_shouldnt_restrict_explicit_type() {
|
||||||
|
let actual = nu!("def foo [x: any = null] { $x }; foo 1");
|
||||||
|
assert_eq!(actual.out, "1");
|
||||||
|
let actual2 = nu!("def foo [--x: any = null] { $x }; foo --x 1");
|
||||||
|
assert_eq!(actual2.out, "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn def_default_value_should_restrict_implicit_type() {
|
||||||
|
let actual = nu!("def foo [x = 3] { $x }; foo 3.0");
|
||||||
|
assert!(actual.err.contains("expected int"));
|
||||||
|
let actual2 = nu!("def foo2 [--x = 3] { $x }; foo2 --x 3.0");
|
||||||
|
assert!(actual2.err.contains("expected int"));
|
||||||
|
}
|
||||||
|
|
|
@ -3374,6 +3374,7 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||||
|
|
||||||
let mut args: Vec<Arg> = vec![];
|
let mut args: Vec<Arg> = vec![];
|
||||||
let mut parse_mode = ParseMode::ArgMode;
|
let mut parse_mode = ParseMode::ArgMode;
|
||||||
|
let mut arg_explicit_type = false;
|
||||||
|
|
||||||
for token in &output {
|
for token in &output {
|
||||||
match token {
|
match token {
|
||||||
|
@ -3428,6 +3429,7 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||||
working_set.error(ParseError::Expected("default value", span));
|
working_set.error(ParseError::Expected("default value", span));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
arg_explicit_type = false;
|
||||||
} else {
|
} else {
|
||||||
match parse_mode {
|
match parse_mode {
|
||||||
ParseMode::ArgMode | ParseMode::AfterCommaArgMode => {
|
ParseMode::ArgMode | ParseMode::AfterCommaArgMode => {
|
||||||
|
@ -3710,6 +3712,7 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
arg_explicit_type = true;
|
||||||
}
|
}
|
||||||
parse_mode = ParseMode::ArgMode;
|
parse_mode = ParseMode::ArgMode;
|
||||||
}
|
}
|
||||||
|
@ -3732,10 +3735,12 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||||
let var_type = &working_set.get_variable(var_id).ty;
|
let var_type = &working_set.get_variable(var_id).ty;
|
||||||
match var_type {
|
match var_type {
|
||||||
Type::Any => {
|
Type::Any => {
|
||||||
working_set.set_variable_type(
|
if !arg_explicit_type {
|
||||||
var_id,
|
working_set.set_variable_type(
|
||||||
expression.ty.clone(),
|
var_id,
|
||||||
);
|
expression.ty.clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if !type_compatible(var_type, &expression.ty) {
|
if !type_compatible(var_type, &expression.ty) {
|
||||||
|
@ -3763,7 +3768,9 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
*shape = expression.ty.to_shape();
|
if !arg_explicit_type {
|
||||||
|
*shape = expression.ty.to_shape();
|
||||||
|
}
|
||||||
*required = false;
|
*required = false;
|
||||||
}
|
}
|
||||||
Arg::RestPositional(..) => {
|
Arg::RestPositional(..) => {
|
||||||
|
@ -3800,9 +3807,13 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||||
if var_type != &Type::Bool {
|
if var_type != &Type::Bool {
|
||||||
match var_type {
|
match var_type {
|
||||||
Type::Any => {
|
Type::Any => {
|
||||||
*arg = Some(expression_ty.to_shape());
|
if !arg_explicit_type {
|
||||||
working_set
|
*arg = Some(expression_ty.to_shape());
|
||||||
.set_variable_type(var_id, expression_ty);
|
working_set.set_variable_type(
|
||||||
|
var_id,
|
||||||
|
expression_ty,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
t => {
|
t => {
|
||||||
if t != &expression_ty {
|
if t != &expression_ty {
|
||||||
|
|
Loading…
Reference in a new issue