diff --git a/crates/nu-protocol/src/eval_const.rs b/crates/nu-protocol/src/eval_const.rs index b387de4120..e68828cfdd 100644 --- a/crates/nu-protocol/src/eval_const.rs +++ b/crates/nu-protocol/src/eval_const.rs @@ -5,8 +5,9 @@ use crate::{ ast::{Assignment, Block, Call, Expr, Expression, ExternalArgument}, debugger::{DebugContext, WithoutDebug}, - engine::{EngineState, StateWorkingSet}, + engine::{Closure, EngineState, StateWorkingSet}, eval_base::Eval, + ir::Instruction, record, BlockId, Config, HistoryFileFormat, PipelineData, Record, ShellError, Span, Value, VarId, }; @@ -548,12 +549,41 @@ impl Eval for EvalConst { } fn eval_row_condition_or_closure( - _: &StateWorkingSet, + state: &StateWorkingSet, _: &mut (), - _: BlockId, + block_id: BlockId, span: Span, ) -> Result { - Err(ShellError::NotAConstant { span }) + let block = state.get_block(block_id); + let ir_block = block + .ir_block + .as_ref() + .ok_or(ShellError::NotAConstant { span })?; + + let non_const_var_idx = ir_block.instructions.iter().position(|ins| { + let Instruction::LoadVariable { var_id, .. } = ins else { + return false; + }; + let var = state.get_variable(*var_id); + !(var.const_val.is_some() + || block + .span + .is_some_and(|b| b.contains_span(var.declaration_span))) + }); + + if let Some(idx) = non_const_var_idx { + Err(ShellError::NotAConstant { + span: ir_block.spans[idx], + }) + } else { + Ok(Value::closure( + Closure { + block_id, + captures: vec![], + }, + span, + )) + } } fn eval_overlay(_: &StateWorkingSet, span: Span) -> Result {