mirror of
https://github.com/nushell/nushell
synced 2025-01-14 22:24:54 +00:00
Change type of parameter default values to Option<Value>
(#8940)
# Description
Fixes #8939.
# User-Facing Changes
- Parameter default values will now be parsed as constants.
- If the default value is not a constant, a parser error is displayed.
# Tests + Formatting
The [only affected
test](d42c2b2dbc/src/tests/test_engine.rs (L325-L328)
)
has been updated to reflect the new behavior.
This commit is contained in:
parent
77ca73f414
commit
e251f3a0b4
5 changed files with 31 additions and 7 deletions
|
@ -72,9 +72,8 @@ pub fn eval_call(
|
||||||
if let Some(arg) = call.positional_nth(param_idx) {
|
if let Some(arg) = call.positional_nth(param_idx) {
|
||||||
let result = eval_expression(engine_state, caller_stack, arg)?;
|
let result = eval_expression(engine_state, caller_stack, arg)?;
|
||||||
callee_stack.add_var(var_id, result);
|
callee_stack.add_var(var_id, result);
|
||||||
} else if let Some(arg) = ¶m.default_value {
|
} else if let Some(value) = ¶m.default_value {
|
||||||
let result = eval_expression(engine_state, caller_stack, arg)?;
|
callee_stack.add_var(var_id, value.to_owned());
|
||||||
callee_stack.add_var(var_id, result);
|
|
||||||
} else {
|
} else {
|
||||||
callee_stack.add_var(var_id, Value::nothing(call.head));
|
callee_stack.add_var(var_id, Value::nothing(call.head));
|
||||||
}
|
}
|
||||||
|
|
|
@ -3735,8 +3735,19 @@ pub fn parse_signature_helper(working_set: &mut StateWorkingSet, span: Span) ->
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*default_value = if let Ok(constant) =
|
||||||
|
eval_constant(working_set, &expression)
|
||||||
|
{
|
||||||
|
Some(constant)
|
||||||
|
} else {
|
||||||
|
working_set.error(ParseError::NonConstantDefaultValue(
|
||||||
|
expression.span,
|
||||||
|
));
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
*shape = expression.ty.to_shape();
|
*shape = expression.ty.to_shape();
|
||||||
*default_value = Some(expression);
|
|
||||||
*required = false;
|
*required = false;
|
||||||
}
|
}
|
||||||
Arg::RestPositional(..) => {
|
Arg::RestPositional(..) => {
|
||||||
|
|
|
@ -338,6 +338,10 @@ pub enum ParseError {
|
||||||
#[label = "parameter {0} needs to be '{1}' instead of '{2}'"] Span,
|
#[label = "parameter {0} needs to be '{1}' instead of '{2}'"] Span,
|
||||||
),
|
),
|
||||||
|
|
||||||
|
#[error("Default values should be constant expressions.")]
|
||||||
|
#[diagnostic(code(nu::parser::non_constant_default_value))]
|
||||||
|
NonConstantDefaultValue(#[label = "expected a constant value"] Span),
|
||||||
|
|
||||||
#[error("Extra columns.")]
|
#[error("Extra columns.")]
|
||||||
#[diagnostic(code(nu::parser::extra_columns))]
|
#[diagnostic(code(nu::parser::extra_columns))]
|
||||||
ExtraColumns(
|
ExtraColumns(
|
||||||
|
@ -472,6 +476,7 @@ impl ParseError {
|
||||||
ParseError::IncompleteParser(s) => *s,
|
ParseError::IncompleteParser(s) => *s,
|
||||||
ParseError::RestNeedsName(s) => *s,
|
ParseError::RestNeedsName(s) => *s,
|
||||||
ParseError::ParameterMismatchType(_, _, _, s) => *s,
|
ParseError::ParameterMismatchType(_, _, _, s) => *s,
|
||||||
|
ParseError::NonConstantDefaultValue(s) => *s,
|
||||||
ParseError::ExtraColumns(_, s) => *s,
|
ParseError::ExtraColumns(_, s) => *s,
|
||||||
ParseError::MissingColumns(_, s) => *s,
|
ParseError::MissingColumns(_, s) => *s,
|
||||||
ParseError::AssignmentMismatch(_, _, s) => *s,
|
ParseError::AssignmentMismatch(_, _, s) => *s,
|
||||||
|
|
|
@ -11,6 +11,7 @@ use crate::PipelineData;
|
||||||
use crate::ShellError;
|
use crate::ShellError;
|
||||||
use crate::SyntaxShape;
|
use crate::SyntaxShape;
|
||||||
use crate::Type;
|
use crate::Type;
|
||||||
|
use crate::Value;
|
||||||
use crate::VarId;
|
use crate::VarId;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ pub struct PositionalArg {
|
||||||
|
|
||||||
// For custom commands
|
// For custom commands
|
||||||
pub var_id: Option<VarId>,
|
pub var_id: Option<VarId>,
|
||||||
pub default_value: Option<Expression>,
|
pub default_value: Option<Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
|
|
@ -323,8 +323,16 @@ fn default_value12() -> TestResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn default_value_expression() -> TestResult {
|
fn default_value_constant() -> TestResult {
|
||||||
run_test(r#"def foo [x = ("foo" | str length)] { $x }; foo"#, "3")
|
run_test(r#"def foo [x = "foo"] { $x }; foo"#, "foo")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn default_value_not_constant() -> TestResult {
|
||||||
|
fail_test(
|
||||||
|
r#"def foo [x = ("foo" | str length)] { $x }; foo"#,
|
||||||
|
"expected a constant",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in a new issue