Use Vec for Closure captures (#10940)

# Description
Changes the `captures` field in `Closure` from a `HashMap` to a `Vec`
and makes `Stack::captures_to_stack` take an owned `Vec` instead of a
borrowed `HashMap`.

This eliminates the conversion to a `Vec` inside `captures_to_stack` and
makes it possible to avoid clones altogether when using an owned
`Closure` (which is the case for most commands). Additionally, using a
`Vec` reduces the size of `Value` by 8 bytes (down to 72).

# User-Facing Changes
Breaking API change for `nu-protocol`.
This commit is contained in:
Ian Manske
2023-11-07 23:43:28 +00:00
committed by GitHub
parent 7a3cbf43e8
commit 60da7abbc7
33 changed files with 46 additions and 59 deletions

View File

@ -524,19 +524,15 @@ pub fn eval_expression(
)
}
Expr::RowCondition(block_id) | Expr::Closure(block_id) => {
let mut captures = HashMap::new();
let block = engine_state.get_block(*block_id);
let block_id = *block_id;
let captures = engine_state
.get_block(block_id)
.captures
.iter()
.map(|&id| stack.get_var(id, expr.span).map(|var| (id, var)))
.collect::<Result<_, _>>()?;
for var_id in &block.captures {
captures.insert(*var_id, stack.get_var(*var_id, expr.span)?);
}
Ok(Value::closure(
Closure {
block_id: *block_id,
captures,
},
expr.span,
))
Ok(Value::closure(Closure { block_id, captures }, expr.span))
}
Expr::Block(block_id) => Ok(Value::block(*block_id, expr.span)),
Expr::List(x) => {