git.delta.rocks / jrsonnet / refs/commits / d6e3ee65093c

difftreelog

fix align object iteration with context refactor

wnuqoyquYaroslav Bolyukin2026-04-25parent: #e9c741d.patch.diff
in: master

2 files changed

modifiedcrates/jrsonnet-evaluator/src/evaluate/destructure.rsdiffbeforeafterboth
1use jrsonnet_ir::{BindSpec, Destruct};1use jrsonnet_ir::{BindSpec, Destruct};
22
3#[cfg(feature = "exp-preserve-order")]
4use crate::evaluate;
5use crate::{3use crate::{
6 Context, ContextBuilder, Pending, Thunk, Val, error::Result, evaluate_method,4 Context, ContextBuilder, Pending, Thunk, Val, error::Result, evaluate_method,
7 evaluate_named_param,5 evaluate_named_param,
25 Destruct::Array { start, rest, end } => {23 Destruct::Array { start, rest, end } => {
26 use jrsonnet_ir::DestructRest;24 use jrsonnet_ir::DestructRest;
25
26 use crate::bail;
2727
28 let min_len = start.len() + end.len();28 let min_len = start.len() + end.len();
29 let has_rest = rest.is_some();29 let has_rest = rest.is_some();
102 use jrsonnet_ir::DestructRest;102 use jrsonnet_ir::DestructRest;
103 use rustc_hash::FxHashSet;103 use rustc_hash::FxHashSet;
104104
105 use crate::ObjValueBuilder;105 use crate::{ObjValueBuilder, bail};
106106
107 let captured_fields: FxHashSet<_> = fields.iter().map(|f| f.0.clone()).collect();107 let captured_fields: FxHashSet<_> = fields.iter().map(|f| f.0.clone()).collect();
108 let field_names: Vec<_> = fields108 let field_names: Vec<_> = fields
modifiedcrates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth
--- 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),