mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 02:55:07 +02:00
fix rest parameter spans (#16176)
Closes #16071 # Description Rest parameter variables are now fully spanned, instead of just the first value: ```diff def foo [...rest] { metadata $rest | view span $in.span.start $in.span.end } foo 1 2 -1 +1 2 ```
This commit is contained in:
@ -1159,6 +1159,7 @@ fn gather_arguments(
|
||||
|
||||
// Arguments that didn't get consumed by required/optional
|
||||
let mut rest = vec![];
|
||||
let mut rest_span: Option<Span> = None;
|
||||
|
||||
// If we encounter a spread, all further positionals should go to rest
|
||||
let mut always_spread = false;
|
||||
@ -1178,12 +1179,19 @@ fn gather_arguments(
|
||||
}
|
||||
callee_stack.add_var(var_id, val);
|
||||
} else {
|
||||
rest_span = Some(rest_span.map_or(val.span(), |s| s.append(val.span())));
|
||||
rest.push(val);
|
||||
}
|
||||
}
|
||||
Argument::Spread { vals, .. } => {
|
||||
Argument::Spread {
|
||||
vals,
|
||||
span: spread_span,
|
||||
..
|
||||
} => {
|
||||
if let Value::List { vals, .. } = vals {
|
||||
rest.extend(vals);
|
||||
// Rest variable should span the spread syntax, not the list values
|
||||
rest_span = Some(rest_span.map_or(spread_span, |s| s.append(spread_span)));
|
||||
// All further positional args should go to spread
|
||||
always_spread = true;
|
||||
} else if let Value::Error { error, .. } = vals {
|
||||
@ -1218,7 +1226,7 @@ fn gather_arguments(
|
||||
|
||||
// Add the collected rest of the arguments if a spread argument exists
|
||||
if let Some(rest_arg) = &block.signature.rest_positional {
|
||||
let rest_span = rest.first().map(|v| v.span()).unwrap_or(call_head);
|
||||
let rest_span = rest_span.unwrap_or(call_head);
|
||||
let var_id = expect_positional_var_id(rest_arg, rest_span)?;
|
||||
callee_stack.add_var(var_id, Value::list(rest, rest_span));
|
||||
}
|
||||
|
Reference in New Issue
Block a user