git.delta.rocks / jrsonnet / refs/commits / 166fbe9afc2a

difftreelog

fix exp-destruct

wkqlwykpYaroslav Bolyukin2026-04-25parent: #a3646b3.patch.diff
in: master

7 files changed

modifiedcrates/jrsonnet-evaluator/src/analyze.rsdiffbeforeafterboth
425 /// h = 1 => referenced += [], closures += 0, destructs += 1425 /// h = 1 => referenced += [], closures += 0, destructs += 1
426 /// And the result is426 /// And the result is
427 ///427 ///
428 /// ```428 /// ```rust,ignore
429 /// Closures {429 /// Closures {
430 /// referenced: vec![d, e, f, a, b, c, h]430 /// referenced: vec![d, e, f, a, b, c, h]
431 /// spec_shapes: vec![(3, 3), (4, 3), (0, 1)],431 /// spec_shapes: vec![(3, 3), (4, 3), (0, 1)],
modifiedcrates/jrsonnet-evaluator/src/evaluate/compspec.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/evaluate/compspec.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/compspec.rs
@@ -195,7 +195,7 @@
 ) -> Result<()> {
 	if idx >= specs.len() {
 		collector.reserve(guaranteed_reserve);
-		return collector.collect(ctx.clone());
+		return collector.collect(ctx);
 	}
 	match &specs[idx] {
 		LCompSpec::If(cond) => {
@@ -239,18 +239,20 @@
 						)?;
 					}
 				}
+				// TODO: Should not be eager? CoW won't work here
 				#[cfg(feature = "exp-destruct")]
 				_ => {
 					for (i, item) in arr.iter().enumerate() {
 						let item_val = item?;
 						let mut inner_builder = ContextBuilder::extend(ctx.clone(), 1);
+						let fctx = Pending::new();
 						destructure::destruct(
 							destruct,
 							Thunk::evaluated(item_val),
-							None,
+							fctx.clone(),
 							&mut inner_builder,
 						);
-						let inner_ctx = inner_builder.build();
+						let inner_ctx = inner_builder.build().into_future(fctx);
 						evaluate_compspecs_eager(
 							inner_ctx,
 							specs,
modifiedcrates/jrsonnet-evaluator/src/evaluate/destructure.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/evaluate/destructure.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/destructure.rs
@@ -12,7 +12,7 @@
 #[allow(dead_code, reason = "not dead in exp-destruct")]
 fn destruct_array(
 	start: &[LDestruct],
-	rest: Option<LDestructRest>,
+	rest: Option<&LDestructRest>,
 	end: &[LDestruct],
 
 	value: Thunk<Val>,
@@ -56,7 +56,7 @@
 	if let Some(crate::analyze::LDestructRest::Keep(id)) = rest {
 		let full = full.clone();
 		builder.bind(
-			id,
+			*id,
 			Thunk!(move || {
 				let full = full.evaluate()?;
 				let to = full.len() - end_len;
@@ -88,7 +88,7 @@
 #[allow(dead_code, reason = "not dead in exp-destruct")]
 fn destruct_object(
 	fields: &[LDestructField],
-	rest: Option<LDestructRest>,
+	rest: Option<&LDestructRest>,
 
 	value: Thunk<Val>,
 	fctx: Pending<Context>,
@@ -127,7 +127,7 @@
 	if let Some(crate::analyze::LDestructRest::Keep(id)) = rest {
 		let full = full.clone();
 		builder.bind(
-			id,
+			*id,
 			Thunk!(move || {
 				let full = full.evaluate()?;
 				let mut out = ObjValueBuilder::new();
@@ -178,9 +178,13 @@
 		#[cfg(feature = "exp-destruct")]
 		LDestruct::Skip => {}
 		#[cfg(feature = "exp-destruct")]
-		LDestruct::Array { start, rest, end } => destruct_array(start, rest, end, value, fctx, builder),
+		LDestruct::Array { start, rest, end } => {
+			destruct_array(start, rest.as_ref(), end, value, fctx, builder)
+		}
 		#[cfg(feature = "exp-destruct")]
-		LDestruct::Object { fields, rest } => destruct_object(fields, rest, value, fctx, builder),
+		LDestruct::Object { fields, rest } => {
+			destruct_object(fields, rest.as_ref(), value, fctx, builder)
+		}
 	}
 }
 
modifiedcrates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@redeclared_local.jsonnet.snapdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@redeclared_local.jsonnet.snap
+++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@redeclared_local.jsonnet.snap
@@ -1,7 +1,7 @@
 ---
 source: crates/jrsonnet-evaluator/src/analyze.rs
 expression: rendered
-input_file: crates/jrsonnet-evaluator/src/analyze_tests/redeclared_local.jsonnet
+input_file: crates/jrsonnet-evaluator/src/analysis_tests/redeclared_local.jsonnet
 ---
 --- source ---
 local x = 1, x = 2; x
@@ -10,7 +10,7 @@
 local_dependent_depth: 0
 errored: true
 --- diagnostics ---
-   ·              ╭── variable redeclared: x
+   ·              ╭── local is already defined in the current frame: x
 1  │ local x = 1, x = 2; x 
 2  │  
 --- lir ---
modifiedcrates/jrsonnet-ir-parser/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-ir-parser/src/lib.rs
+++ b/crates/jrsonnet-ir-parser/src/lib.rs
@@ -381,7 +381,7 @@
 				None
 			};
 			let default = if p.try_eat(T![=]) {
-				Some(Rc::new(spanned(p, expr)?))
+				Some(spanned(p, expr)?)
 			} else {
 				None
 			};
@@ -466,8 +466,10 @@
 		if !p.at(SyntaxKind::IDENT) {
 			let d = destruct(p)?;
 			p.eat(T![=])?;
-			let value = Rc::new(expr(p)?);
-			return Ok(BindSpec::Field { into: d, value });
+			return Ok(BindSpec::Field {
+				into: d,
+				value: expr(p)?,
+			});
 		}
 	}
 	let name_spanned = spanned(p, ident)?;
modifiedcrates/jrsonnet-ir/src/expr.rsdiffbeforeafterboth
--- a/crates/jrsonnet-ir/src/expr.rs
+++ b/crates/jrsonnet-ir/src/expr.rs
@@ -211,7 +211,7 @@
 	}
 }
 
-#[derive(Debug, Clone, PartialEq, Eq, Acyclic)]
+#[derive(Debug, PartialEq, Eq, Acyclic)]
 pub enum DestructRest {
 	/// ...rest
 	Keep(IStr),
@@ -219,7 +219,7 @@
 	Drop,
 }
 
-#[derive(Debug, Clone, PartialEq, Acyclic)]
+#[derive(Debug, PartialEq, Acyclic)]
 pub enum Destruct {
 	Full(Spanned<IStr>),
 	#[cfg(feature = "exp-destruct")]
@@ -233,7 +233,7 @@
 	#[cfg(feature = "exp-destruct")]
 	Object {
 		#[allow(clippy::type_complexity)]
-		fields: Vec<(IStr, Option<Destruct>, Option<Rc<Spanned<Expr>>>)>,
+		fields: Vec<(IStr, Option<Destruct>, Option<Spanned<Expr>>)>,
 		rest: Option<DestructRest>,
 	},
 }
modifiedcrates/jrsonnet-peg-parser/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-peg-parser/src/lib.rs
+++ b/crates/jrsonnet-peg-parser/src/lib.rs
@@ -1,5 +1,3 @@
-use std::rc::Rc;
-
 use jrsonnet_gcmodule::Acyclic;
 use jrsonnet_ir::{
 	ArgsDesc, AssertExpr, AssertStmt, BinaryOp, BindSpec, CompSpec, Destruct, DestructRest, Expr,
@@ -110,7 +108,7 @@
 			}
 		pub rule destruct_object(s: &ParserSettings) -> Destruct
 			= "{" _
-				fields:(name:id() into:(_ ":" _ into:destruct(s) {into})? default:(_ "=" _ v:spanned(<expr(s)>, s) {v})? {(name, into, default.map(Rc::new))})**comma()
+				fields:(name:id() into:(_ ":" _ into:destruct(s) {into})? default:(_ "=" _ v:spanned(<expr(s)>, s) {v})? {(name, into, default)})**comma()
 				rest:(
 					comma() rest:destruct_rest()? {rest}
 					/ comma()? {None}