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
195) -> Result<()> {195) -> Result<()> {
196 if idx >= specs.len() {196 if idx >= specs.len() {
197 collector.reserve(guaranteed_reserve);197 collector.reserve(guaranteed_reserve);
198 return collector.collect(ctx.clone());198 return collector.collect(ctx);
199 }199 }
200 match &specs[idx] {200 match &specs[idx] {
201 LCompSpec::If(cond) => {201 LCompSpec::If(cond) => {
239 )?;239 )?;
240 }240 }
241 }241 }
242 // TODO: Should not be eager? CoW won't work here
242 #[cfg(feature = "exp-destruct")]243 #[cfg(feature = "exp-destruct")]
243 _ => {244 _ => {
244 for (i, item) in arr.iter().enumerate() {245 for (i, item) in arr.iter().enumerate() {
245 let item_val = item?;246 let item_val = item?;
246 let mut inner_builder = ContextBuilder::extend(ctx.clone(), 1);247 let mut inner_builder = ContextBuilder::extend(ctx.clone(), 1);
248 let fctx = Pending::new();
247 destructure::destruct(249 destructure::destruct(
248 destruct,250 destruct,
249 Thunk::evaluated(item_val),251 Thunk::evaluated(item_val),
250 None,252 fctx.clone(),
251 &mut inner_builder,253 &mut inner_builder,
252 );254 );
253 let inner_ctx = inner_builder.build();255 let inner_ctx = inner_builder.build().into_future(fctx);
254 evaluate_compspecs_eager(256 evaluate_compspecs_eager(
255 inner_ctx,257 inner_ctx,
256 specs,258 specs,
modifiedcrates/jrsonnet-evaluator/src/evaluate/destructure.rsdiffbeforeafterboth
12#[allow(dead_code, reason = "not dead in exp-destruct")]12#[allow(dead_code, reason = "not dead in exp-destruct")]
13fn destruct_array(13fn destruct_array(
14 start: &[LDestruct],14 start: &[LDestruct],
15 rest: Option<LDestructRest>,15 rest: Option<&LDestructRest>,
16 end: &[LDestruct],16 end: &[LDestruct],
1717
18 value: Thunk<Val>,18 value: Thunk<Val>,
56 if let Some(crate::analyze::LDestructRest::Keep(id)) = rest {56 if let Some(crate::analyze::LDestructRest::Keep(id)) = rest {
57 let full = full.clone();57 let full = full.clone();
58 builder.bind(58 builder.bind(
59 id,59 *id,
60 Thunk!(move || {60 Thunk!(move || {
61 let full = full.evaluate()?;61 let full = full.evaluate()?;
62 let to = full.len() - end_len;62 let to = full.len() - end_len;
88#[allow(dead_code, reason = "not dead in exp-destruct")]88#[allow(dead_code, reason = "not dead in exp-destruct")]
89fn destruct_object(89fn destruct_object(
90 fields: &[LDestructField],90 fields: &[LDestructField],
91 rest: Option<LDestructRest>,91 rest: Option<&LDestructRest>,
9292
93 value: Thunk<Val>,93 value: Thunk<Val>,
94 fctx: Pending<Context>,94 fctx: Pending<Context>,
127 if let Some(crate::analyze::LDestructRest::Keep(id)) = rest {127 if let Some(crate::analyze::LDestructRest::Keep(id)) = rest {
128 let full = full.clone();128 let full = full.clone();
129 builder.bind(129 builder.bind(
130 id,130 *id,
131 Thunk!(move || {131 Thunk!(move || {
132 let full = full.evaluate()?;132 let full = full.evaluate()?;
133 let mut out = ObjValueBuilder::new();133 let mut out = ObjValueBuilder::new();
178 #[cfg(feature = "exp-destruct")]178 #[cfg(feature = "exp-destruct")]
179 LDestruct::Skip => {}179 LDestruct::Skip => {}
180 #[cfg(feature = "exp-destruct")]180 #[cfg(feature = "exp-destruct")]
181 LDestruct::Array { start, rest, end } => destruct_array(start, rest, end, value, fctx, builder),181 LDestruct::Array { start, rest, end } => {
182 destruct_array(start, rest.as_ref(), end, value, fctx, builder)
183 }
182 #[cfg(feature = "exp-destruct")]184 #[cfg(feature = "exp-destruct")]
183 LDestruct::Object { fields, rest } => destruct_object(fields, rest, value, fctx, builder),185 LDestruct::Object { fields, rest } => {
186 destruct_object(fields, rest.as_ref(), value, fctx, builder)
187 }
184 }188 }
185}189}
186190
modifiedcrates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@redeclared_local.jsonnet.snapdiffbeforeafterboth
1---1---
2source: crates/jrsonnet-evaluator/src/analyze.rs2source: crates/jrsonnet-evaluator/src/analyze.rs
3expression: rendered3expression: rendered
4input_file: crates/jrsonnet-evaluator/src/analyze_tests/redeclared_local.jsonnet4input_file: crates/jrsonnet-evaluator/src/analysis_tests/redeclared_local.jsonnet
5---5---
6--- source ---6--- source ---
7local x = 1, x = 2; x7local x = 1, x = 2; x
10local_dependent_depth: 010local_dependent_depth: 0
11errored: true11errored: true
12--- diagnostics ---12--- diagnostics ---
13 · ╭── variable redeclared: x13 · ╭── local is already defined in the current frame: x
141 │ local x = 1, x = 2; x 141 │ local x = 1, x = 2; x
152 │ 152 │
16--- lir ---16--- lir ---
modifiedcrates/jrsonnet-ir-parser/src/lib.rsdiffbeforeafterboth
381 None381 None
382 };382 };
383 let default = if p.try_eat(T![=]) {383 let default = if p.try_eat(T![=]) {
384 Some(Rc::new(spanned(p, expr)?))384 Some(spanned(p, expr)?)
385 } else {385 } else {
386 None386 None
387 };387 };
466 if !p.at(SyntaxKind::IDENT) {466 if !p.at(SyntaxKind::IDENT) {
467 let d = destruct(p)?;467 let d = destruct(p)?;
468 p.eat(T![=])?;468 p.eat(T![=])?;
469 let value = Rc::new(expr(p)?);469 return Ok(BindSpec::Field {
470 return Ok(BindSpec::Field { into: d, value });470 into: d,
471 value: expr(p)?,
472 });
471 }473 }
472 }474 }
473 let name_spanned = spanned(p, ident)?;475 let name_spanned = spanned(p, ident)?;
modifiedcrates/jrsonnet-ir/src/expr.rsdiffbeforeafterboth
211 }211 }
212}212}
213213
214#[derive(Debug, Clone, PartialEq, Eq, Acyclic)]214#[derive(Debug, PartialEq, Eq, Acyclic)]
215pub enum DestructRest {215pub enum DestructRest {
216 /// ...rest216 /// ...rest
217 Keep(IStr),217 Keep(IStr),
218 /// ...218 /// ...
219 Drop,219 Drop,
220}220}
221221
222#[derive(Debug, Clone, PartialEq, Acyclic)]222#[derive(Debug, PartialEq, Acyclic)]
223pub enum Destruct {223pub enum Destruct {
224 Full(Spanned<IStr>),224 Full(Spanned<IStr>),
225 #[cfg(feature = "exp-destruct")]225 #[cfg(feature = "exp-destruct")]
233 #[cfg(feature = "exp-destruct")]233 #[cfg(feature = "exp-destruct")]
234 Object {234 Object {
235 #[allow(clippy::type_complexity)]235 #[allow(clippy::type_complexity)]
236 fields: Vec<(IStr, Option<Destruct>, Option<Rc<Spanned<Expr>>>)>,236 fields: Vec<(IStr, Option<Destruct>, Option<Spanned<Expr>>)>,
237 rest: Option<DestructRest>,237 rest: Option<DestructRest>,
238 },238 },
239}239}
modifiedcrates/jrsonnet-peg-parser/src/lib.rsdiffbeforeafterboth
1use std::rc::Rc;
2
3use jrsonnet_gcmodule::Acyclic;1use jrsonnet_gcmodule::Acyclic;
4use jrsonnet_ir::{2use jrsonnet_ir::{
110 }108 }
111 pub rule destruct_object(s: &ParserSettings) -> Destruct109 pub rule destruct_object(s: &ParserSettings) -> Destruct
112 = "{" _110 = "{" _
113 fields:(name:id() into:(_ ":" _ into:destruct(s) {into})? default:(_ "=" _ v:spanned(<expr(s)>, s) {v})? {(name, into, default.map(Rc::new))})**comma()111 fields:(name:id() into:(_ ":" _ into:destruct(s) {into})? default:(_ "=" _ v:spanned(<expr(s)>, s) {v})? {(name, into, default)})**comma()
114 rest:(112 rest:(
115 comma() rest:destruct_rest()? {rest}113 comma() rest:destruct_rest()? {rest}
116 / comma()? {None}114 / comma()? {None}