Make timeit take only closures as an argument (#14483)

# Description

Fixes #14401 where expressions passed to `timeit` will execute twice.
This PR removes the expression support for `timeit`, as this behavior is
almost exclusive to `timeit` and can hinder migration to the IR
evaluator in the future. Additionally, `timeit` used to be able to take
a `block` as an argument. Blocks should probably only be allowed for
parser keywords, so this PR changes `timeit` to instead only take
closures as an argument. This also fixes an issue where environment
updates inside the `timeit` block would affect the parent scope and all
commands later in the pipeline.

```nu
> timeit { $env.FOO = 'bar' }; print $env.FOO
bar
```

# User-Facing Changes

`timeit` now only takes a closure as the first argument.

# After Submitting

Update examples in the book/docs if necessary.
This commit is contained in:
Ian Manske
2024-12-10 07:08:53 -08:00
committed by GitHub
parent 3515e3ee28
commit 7d2e8875e0
3 changed files with 65 additions and 36 deletions

View File

@ -88,6 +88,29 @@ impl ClosureEval {
}
}
pub fn new_preserve_out_dest(
engine_state: &EngineState,
stack: &Stack,
closure: Closure,
) -> Self {
let engine_state = engine_state.clone();
let stack = stack.captures_to_stack_preserve_out_dest(closure.captures);
let block = engine_state.get_block(closure.block_id).clone();
let env_vars = stack.env_vars.clone();
let env_hidden = stack.env_hidden.clone();
let eval = get_eval_block_with_early_return(&engine_state);
Self {
engine_state,
stack,
block,
arg_index: 0,
env_vars,
env_hidden,
eval,
}
}
/// Sets whether to enable debugging when evaluating the closure.
///
/// By default, this is controlled by the [`EngineState`] used to create this [`ClosureEval`].
@ -189,6 +212,22 @@ impl<'a> ClosureEvalOnce<'a> {
}
}
pub fn new_preserve_out_dest(
engine_state: &'a EngineState,
stack: &Stack,
closure: Closure,
) -> Self {
let block = engine_state.get_block(closure.block_id);
let eval = get_eval_block_with_early_return(engine_state);
Self {
engine_state,
stack: stack.captures_to_stack_preserve_out_dest(closure.captures),
block,
arg_index: 0,
eval,
}
}
/// Sets whether to enable debugging when evaluating the closure.
///
/// By default, this is controlled by the [`EngineState`] used to create this [`ClosureEvalOnce`].