Spread operator for list literals (#11006)

This commit is contained in:
ysthakur
2023-11-22 16:10:08 -05:00
committed by GitHub
parent 95a745e622
commit 823e578c46
12 changed files with 149 additions and 13 deletions

View File

@ -45,6 +45,7 @@ pub enum Expr {
Signature(Box<Signature>),
StringInterpolation(Vec<Expression>),
MatchPattern(Box<MatchPattern>),
Spread(Box<Expression>),
Nothing,
Garbage,
}

View File

@ -289,6 +289,7 @@ impl Expression {
Expr::ValueWithUnit(expr, _) => expr.has_in_variable(working_set),
Expr::Var(var_id) => *var_id == IN_VARIABLE_ID,
Expr::VarDecl(_) => false,
Expr::Spread(expr) => expr.has_in_variable(working_set),
}
}
@ -480,6 +481,7 @@ impl Expression {
}
}
Expr::VarDecl(_) => {}
Expr::Spread(expr) => expr.replace_in_variable(working_set, new_var_id),
}
}
@ -618,6 +620,7 @@ impl Expression {
Expr::ValueWithUnit(expr, _) => expr.replace_span(working_set, replaced, new_span),
Expr::Var(_) => {}
Expr::VarDecl(_) => {}
Expr::Spread(expr) => expr.replace_span(working_set, replaced, new_span),
}
}
}

View File

@ -278,7 +278,13 @@ pub fn eval_constant(
Expr::List(x) => {
let mut output = vec![];
for expr in x {
output.push(eval_constant(working_set, expr)?);
match &expr.expr {
Expr::Spread(expr) => match eval_constant(working_set, expr)? {
Value::List { mut vals, .. } => output.append(&mut vals),
_ => return Err(ShellError::CannotSpreadAsList { span: expr.span }),
},
_ => output.push(eval_constant(working_set, expr)?),
}
}
Ok(Value::list(output, expr.span))
}

View File

@ -483,6 +483,10 @@ pub enum ParseError {
#[label("Not allowed here")] Span,
#[label("...and here")] Option<Span>,
),
#[error("Unexpected spread operator outside list")]
#[diagnostic(code(nu::parser::unexpected_spread_operator))]
UnexpectedSpread(#[label("Spread operator not allowed here")] Span),
}
impl ParseError {
@ -569,6 +573,7 @@ impl ParseError {
ParseError::InvalidLiteral(_, _, s) => *s,
ParseError::LabeledErrorWithHelp { span: s, .. } => *s,
ParseError::RedirectionInLetMut(s, _) => *s,
ParseError::UnexpectedSpread(s) => *s,
}
}
}

View File

@ -1170,6 +1170,21 @@ This is an internal Nushell error, please file an issue https://github.com/nushe
)]
//todo: add error detail
ErrorExpandingGlob(String, #[label = "{0}"] Span),
/// Tried spreading a non-list inside a list.
///
/// ## Resolution
///
/// Only lists can be spread inside lists. Try converting the value to a list before spreading.
#[error("Not a list")]
#[diagnostic(
code(nu::shell::cannot_spread),
help("Only lists can be spread inside lists. Try converting the value to a list before spreading")
)]
CannotSpreadAsList {
#[label = "cannot spread value"]
span: Span,
},
}
// TODO: Implement as From trait