From d6e3ee65093ccb1a5901b6b3a45a6798edb37e6b Mon Sep 17 00:00:00 2001 From: Yaroslav Bolyukin Date: Sun, 05 Apr 2026 19:25:11 +0000 Subject: [PATCH] fix: align object iteration with context refactor --- --- a/crates/jrsonnet-evaluator/src/evaluate/destructure.rs +++ b/crates/jrsonnet-evaluator/src/evaluate/destructure.rs @@ -1,7 +1,5 @@ use jrsonnet_ir::{BindSpec, Destruct}; -#[cfg(feature = "exp-preserve-order")] -use crate::evaluate; use crate::{ Context, ContextBuilder, Pending, Thunk, Val, error::Result, evaluate_method, evaluate_named_param, @@ -25,6 +23,8 @@ Destruct::Array { start, rest, end } => { use jrsonnet_ir::DestructRest; + use crate::bail; + let min_len = start.len() + end.len(); let has_rest = rest.is_some(); let full = Thunk!(move || { @@ -102,7 +102,7 @@ use jrsonnet_ir::DestructRest; use rustc_hash::FxHashSet; - use crate::ObjValueBuilder; + use crate::{ObjValueBuilder, bail}; let captured_fields: FxHashSet<_> = fields.iter().map(|f| f.0.clone()).collect(); let field_names: Vec<_> = fields --- a/crates/jrsonnet-evaluator/src/evaluate/mod.rs +++ b/crates/jrsonnet-evaluator/src/evaluate/mod.rs @@ -145,28 +145,36 @@ )?; } } - #[cfg(feature = "exp-object-iteration")] - Val::Obj(obj) => { + Val::Obj(obj) if cfg!(feature = "exp-object-iteration") => { let fields = obj.fields( // TODO: Should there be ability to preserve iteration order? #[cfg(feature = "exp-preserve-order")] false, ); guaranteed_reserve = guaranteed_reserve.max(1) * fields.len(); - for field in fields { + for (i, field) in fields.into_iter().enumerate() { let fctx = Pending::new(); - let mut new_bindings = FxHashMap::with_capacity(into.binds_len()); + let mut ctx = ContextBuilder::extend_fast(ctx.clone()); let obj = obj.clone(); let value = Thunk::evaluated(Val::arr(vec![ Thunk::evaluated(Val::string(field.clone())), - obj.get_lazy(field).transpose().expect( + obj.get_lazy(field).expect( "field exists, as field name was obtained from object.fields()", ), ])); - destruct(into, value, fctx.clone(), &mut new_bindings)?; - let ctx = ctx.clone().extend_bindings(new_bindings).into_future(fctx); + destruct(into, value, fctx.clone(), &mut ctx)?; + let ctx = ctx.build().into_future(fctx); - evaluate_comp(ctx, &specs[1..], callback)?; + evaluate_comp( + ctx, + &specs[1..], + if i == 0 || !specs.is_empty() { + guaranteed_reserve + } else { + 0 + }, + callback, + )?; } } _ => bail!(InComprehensionCanOnlyIterateOverArray), -- gitstuff