--- a/crates/jrsonnet-evaluator/src/analyze.rs +++ b/crates/jrsonnet-evaluator/src/analyze.rs @@ -21,16 +21,18 @@ use jrsonnet_interner::IStr; use jrsonnet_ir::{ ArgsDesc, AssertExpr, AssertStmt, BinaryOp, BinaryOpType, BindSpec, CompSpec, Destruct, Expr, - ExprParams, FieldName, ForSpecData, IfElse, IfSpecData, ImportKind, LiteralType, NumValue, - ObjBody, ObjComp, ObjMembers, Slice, SliceDesc, Span, Spanned, UnaryOpType, Visibility, + ExprParams, FieldName, ForSpecData, IdentityKind, IfElse, IfSpecData, ImportKind, ObjBody, + ObjComp, ObjMembers, Slice, SliceDesc, Span, Spanned, TrivialVal, UnaryOpType, Visibility, function::FunctionSignature, }; -use rustc_hash::FxHashMap; +use rustc_hash::{FxHashMap, FxHashSet}; use smallvec::SmallVec; use crate::{ arr::arridx, error::{format_found, suggest_names}, + gc::WithCapacityExt as _, + obj::{ObjFieldFlags, ObjShape, ShapeField, ordering::FieldIndex}, }; #[derive(Debug, Clone, Copy)] @@ -329,6 +331,7 @@ #[derive(Debug, Acyclic)] pub enum LObjBody { MemberList(LObjMembers), + StaticMembers(Box), ObjComp(Box), } @@ -349,6 +352,20 @@ } #[derive(Debug, Acyclic)] +pub struct LObjStaticMembers { + pub frame_shape: ClosureShape, + pub this: Option, + pub set_dollar: bool, + pub uses_super: bool, + + pub locals: Rc>, + pub asserts: Option>, + + pub shape: Rc, + pub bindings: Vec>, +} + +#[derive(Debug, Acyclic)] pub struct LObjComp { pub frame_shape: Rc, pub this: Option, @@ -1336,7 +1353,7 @@ taint: &mut AnalysisResult, ) -> LExpr { if let Expr::Function(span, params, body) = expr { - return analyze_function(Some(name), &span, ¶ms, body, stack, taint); + return analyze_function(Some(name), span, params, body, stack, taint); } analyze(expr, stack, taint) } @@ -1552,7 +1569,7 @@ BindSpec::Field { value: Expr::Function(span, params, value), into: Destruct::Full(name), - } => analyze_function(Some(name.value.clone()), &span, params, value, stack, taint), + } => analyze_function(Some(name.value.clone()), span, params, value, stack, taint), BindSpec::Field { value, .. } => analyze(value, stack, taint), BindSpec::Function { params, @@ -1694,12 +1711,69 @@ ) -> LObjBody { match obj { ObjBody::MemberList(members) => { - LObjBody::MemberList(analyze_obj_members(members, stack, taint)) + let lowered = analyze_obj_members(members, stack, taint); + match try_lower_static(lowered) { + Ok(static_members) => LObjBody::StaticMembers(Box::new(static_members)), + Err(member_list) => LObjBody::MemberList(member_list), + } } ObjBody::ObjComp(comp) => LObjBody::ObjComp(Box::new(analyze_obj_comp(comp, stack, taint))), } } +fn try_lower_static(members: LObjMembers) -> Result { + let mut seen: FxHashSet = FxHashSet::with_capacity(members.fields.len()); + for f in &members.fields { + match &f.name { + LFieldName::Fixed(name) => { + if !seen.insert(name.clone()) { + return Err(members); + } + } + LFieldName::Dyn(_) => return Err(members), + } + } + + let LObjMembers { + frame_shape, + this, + set_dollar, + uses_super, + locals, + asserts, + fields, + } = members; + + let mut shape_fields = Vec::with_capacity(fields.len()); + let mut bindings = Vec::with_capacity(fields.len()); + let mut next_index = FieldIndex::default(); + for f in fields { + let LFieldName::Fixed(name) = f.name else { + unreachable!("checked above"); + }; + let index = next_index; + next_index = next_index.next(); + shape_fields.push(ShapeField { + name, + flags: ObjFieldFlags::new(f.plus, f.visibility), + location: None, + index, + }); + bindings.push(f.value); + } + + Ok(LObjStaticMembers { + frame_shape, + this, + set_dollar, + uses_super, + locals, + asserts, + shape: Rc::new(ObjShape::new(shape_fields)), + bindings, + }) +} + fn analyze_obj_members( members: &ObjMembers, stack: &mut AnalysisStack, --- a/crates/jrsonnet-evaluator/src/evaluate/mod.rs +++ b/crates/jrsonnet-evaluator/src/evaluate/mod.rs @@ -11,11 +11,11 @@ operator::evaluate_binary_op_special, }; use crate::{ - Context, Error, ObjValue, ObjValueBuilder, ObjectAssertion, Result, ResultExt as _, SupThis, - Unbound, Val, + CcObjectAssertion, CcUnbound, Context, Error, MaybeUnbound, ObjValue, ObjValueBuilder, + ObjectAssertion, Result, ResultExt as _, StaticShapeOopObject, SupThis, Unbound, Val, analyze::{ ClosureShape, LArgsDesc, LAssertStmt, LExpr, LFieldMember, LFieldName, LFunction, - LIndexPart, LObjAsserts, LObjBody, LObjMembers, LSlot, + LIndexPart, LObjAsserts, LObjBody, LObjMembers, LObjStaticMembers, LSlot, }, arr::ArrValue, bail, @@ -469,6 +469,9 @@ fn evaluate_obj_body(super_obj: Option, ctx: Context, body: &LObjBody) -> Result { match body { LObjBody::MemberList(members) => evaluate_obj_members(super_obj, ctx, members), + LObjBody::StaticMembers(members) => { + Ok(evaluate_static_obj_members(super_obj, ctx, members)) + } LObjBody::ObjComp(comp) => evaluate_obj_comp(super_obj, ctx, comp), } } @@ -540,6 +543,84 @@ Ok(()) } +fn evaluate_static_obj_members( + super_obj: Option, + ctx: Context, + members: &LObjStaticMembers, +) -> Val { + #[derive(Trace)] + struct UnboundField { + uctx: B, + value: Rc<(ClosureShape, LExpr)>, + name: IStr, + } + impl> Unbound for UnboundField { + type Bound = Val; + fn bind(&self, sup_this: SupThis) -> Result { + let a_ctx = self.uctx.bind(sup_this)?; + let b_ctx = Context::enter_using(&a_ctx, &self.value.0); + evaluate(b_ctx, &self.value.1) + } + } + + let needs_unbound = members.this.is_some() || members.uses_super; + + let mut bindings: Vec = Vec::with_capacity(members.bindings.len()); + + let assertion = if needs_unbound { + let uctx = CachedUnbound::new(evaluate_locals_unbound( + &ctx, + &members.frame_shape, + members.this, + members.locals.clone(), + )); + for (binding, field) in members.bindings.iter().zip(members.shape.fields()) { + if let Some(v) = evaluate_trivial(&binding.1) { + bindings.push(MaybeUnbound::Const(v)); + continue; + } + bindings.push(MaybeUnbound::Unbound(CcUnbound::new(UnboundField { + uctx: uctx.clone(), + value: binding.clone(), + name: field.name.clone(), + }))); + } + members + .asserts + .as_ref() + .map(|a| CcObjectAssertion::new(evaluate_object_assertions_unbound(uctx, a.clone()))) + } else { + let a_ctx = ctx + .pack_captures_sup_this(&members.frame_shape) + .enter(|fill, ctx| { + fill_letrec_binds(fill, ctx, &members.locals); + }); + for binding in &members.bindings { + if let Some(v) = evaluate_trivial(&binding.1) { + bindings.push(MaybeUnbound::Const(v)); + continue; + } + let env = Context::enter_using(&a_ctx, &binding.0); + let value = binding.clone(); + bindings.push(MaybeUnbound::Bound(Thunk!(move || evaluate(env, &value.1)))); + } + members.asserts.as_ref().map(|a| { + CcObjectAssertion::new(evaluate_object_assertions_static(a_ctx.clone(), a.clone())) + }) + }; + + let mut builder = ObjValueBuilder::with_capacity(0); + if let Some(sup) = super_obj { + builder.with_super(sup); + } + builder.extend_with_core(StaticShapeOopObject::new( + members.shape.clone(), + bindings, + assertion, + )); + Val::Obj(builder.build()) +} + fn evaluate_obj_members( super_obj: Option, ctx: Context, --- a/crates/jrsonnet-evaluator/src/lib.rs +++ b/crates/jrsonnet-evaluator/src/lib.rs @@ -144,6 +144,7 @@ Unbound(CcUnbound), /// Value is object-independent Bound(Thunk), + Const(Val), } impl Debug for MaybeUnbound { @@ -157,6 +158,7 @@ match self { Self::Unbound(v) => v.0.bind(sup_this), Self::Bound(v) => Ok(v.evaluate()?), + Self::Const(v) => Ok(v.clone()), } } } --- a/crates/jrsonnet-evaluator/src/obj/mod.rs +++ b/crates/jrsonnet-evaluator/src/obj/mod.rs @@ -17,9 +17,11 @@ use rustc_hash::{FxHashMap, FxHashSet}; mod oop; +mod static_shape; pub use jrsonnet_ir::Visibility; pub use oop::ObjValueBuilder; +pub use static_shape::{ObjShape, ObjShapeBuilder, ShapeField, StaticShapeOopObject}; use crate::{ CcUnbound, MaybeUnbound, Result, Thunk, Unbound, Val, @@ -99,7 +101,7 @@ #[derive(Clone, Copy, Acyclic)] pub struct ObjFieldFlags(u8); impl ObjFieldFlags { - fn new(add: bool, visibility: Visibility) -> Self { + pub fn new(add: bool, visibility: Visibility) -> Self { let mut v = 0; if add { v |= 1; @@ -140,7 +142,7 @@ pub location: Option, } -cc_dyn!(CcObjectAssertion, ObjectAssertion); +cc_dyn!(CcObjectAssertion, ObjectAssertion, pub fn new() {...}); pub trait ObjectAssertion: Trace { fn run(&self, sup_this: SupThis) -> Result<()>; } @@ -203,6 +205,10 @@ fn field_visibility_core(&self, field: IStr) -> FieldVisibility; fn run_assertions_core(&self, sup_this: SupThis) -> Result<()>; + + fn has_assertion(&self) -> bool { + false + } } #[derive(Clone, Trace)] @@ -1117,7 +1123,7 @@ pub struct ExtendBuilder<'v>(&'v mut ObjValue); impl ObjMemberBuilder> { pub fn value(self, value: impl Into) { - self.binding(MaybeUnbound::Bound(Thunk::evaluated(value.into()))); + self.binding(MaybeUnbound::Const(value.into())); } pub fn bindable(self, bindable: impl Unbound) { self.binding(MaybeUnbound::Unbound(CcUnbound::new(bindable))); --- a/crates/jrsonnet-evaluator/src/obj/oop.rs +++ b/crates/jrsonnet-evaluator/src/obj/oop.rs @@ -113,6 +113,10 @@ } Ok(()) } + + fn has_assertion(&self) -> bool { + self.assertion.is_some() + } } #[allow(clippy::module_name_repetitions)] @@ -177,6 +181,7 @@ pub fn extend_with_core(&mut self, core: impl ObjectCore) { self.commit(); + self.has_assertions |= core.has_assertion(); self.sup.push(CcObjectCore::new(core)); } @@ -219,8 +224,7 @@ impl ObjMemberBuilder> { /// Inserts value, replacing if it is already defined pub fn value(self, value: impl Into) { - let (receiver, name, idx, member) = - self.build_member(MaybeUnbound::Bound(Thunk::evaluated(value.into()))); + let (receiver, name, idx, member) = self.build_member(MaybeUnbound::Const(value.into())); let entry = receiver.0.new.this_entries.entry(name); entry.insert_entry((member, idx)); } @@ -233,7 +237,7 @@ /// Tries to insert value, returns an error if it was already defined pub fn try_value(self, value: impl Into) -> Result<()> { - self.try_thunk(Thunk::evaluated(value.into())) + self.binding(MaybeUnbound::Const(value.into())) } pub fn try_thunk(self, value: impl Into>) -> Result<()> { self.binding(MaybeUnbound::Bound(value.into())) --- /dev/null +++ b/crates/jrsonnet-evaluator/src/obj/static_shape.rs @@ -0,0 +1,213 @@ +use std::{fmt, ops::ControlFlow, rc::Rc}; + +use jrsonnet_gcmodule::{Acyclic, Trace, TraceBox}; +use jrsonnet_interner::IStr; +use jrsonnet_ir::Span; + +use super::{ + CcObjectAssertion, EnumFields, EnumFieldsHandler, FieldVisibility, GetFor, + HasFieldIncludeHidden, ObjFieldFlags, ObjectCore, SupThis, Visibility, + ordering::{FieldIndex, SuperDepth}, +}; +use crate::{MaybeUnbound, Result}; + +#[derive(Acyclic, Debug)] +pub struct ShapeField { + pub name: IStr, + pub flags: ObjFieldFlags, + pub location: Option, + pub index: FieldIndex, +} + +#[derive(Acyclic, Debug)] +pub struct ObjShape { + fields: Vec, +} + +impl ObjShape { + #[must_use] + pub fn new(fields: Vec) -> Self { + Self { fields } + } + + #[inline] + pub fn fields(&self) -> &[ShapeField] { + &self.fields + } + + #[inline] + #[must_use] + pub fn len(&self) -> usize { + self.fields.len() + } + + #[inline] + #[must_use] + pub fn is_empty(&self) -> bool { + self.fields.is_empty() + } + + #[inline] + pub fn find_index(&self, name: &IStr) -> Option { + self.fields.iter().position(|f| &f.name == name) + } +} + +#[derive(Trace)] +pub struct StaticShapeOopObject { + shape: Rc, + bindings: TraceBox<[MaybeUnbound]>, + assertion: Option, +} + +impl fmt::Debug for StaticShapeOopObject { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("StaticShapeOopObject") + .field("shape", &self.shape) + .field("has_assertion", &self.assertion.is_some()) + .finish_non_exhaustive() + } +} + +impl StaticShapeOopObject { + pub fn new( + shape: Rc, + bindings: Vec, + assertion: Option, + ) -> Self { + debug_assert_eq!( + shape.fields.len(), + bindings.len(), + "shape arity must match bindings" + ); + Self { + shape, + bindings: TraceBox(bindings.into_boxed_slice()), + assertion, + } + } + + #[inline] + #[must_use] + pub const fn shape(&self) -> &Rc { + &self.shape + } +} + +impl ObjectCore for StaticShapeOopObject { + fn enum_fields_core( + &self, + super_depth: &mut SuperDepth, + handler: &mut EnumFieldsHandler<'_>, + ) -> bool { + for field in &self.shape.fields { + if matches!( + handler( + *super_depth, + field.index, + field.name.clone(), + EnumFields::Normal(field.flags.visibility()), + ), + ControlFlow::Break(()) + ) { + return false; + } + } + true + } + + fn has_field_include_hidden_core(&self, name: IStr) -> HasFieldIncludeHidden { + if self.shape.find_index(&name).is_some() { + HasFieldIncludeHidden::Exists + } else { + HasFieldIncludeHidden::NotFound + } + } + + fn get_for_core(&self, key: IStr, sup_this: SupThis, omit_only: bool) -> Result { + if omit_only { + return Ok(GetFor::NotFound); + } + let Some(i) = self.shape.find_index(&key) else { + return Ok(GetFor::NotFound); + }; + let field = &self.shape.fields[i]; + let v = self.bindings[i].evaluate(sup_this)?; + Ok(if field.flags.add() { + GetFor::SuperPlus(v) + } else { + GetFor::Final(v) + }) + } + + fn field_visibility_core(&self, field: IStr) -> FieldVisibility { + self.shape + .find_index(&field) + .map_or(FieldVisibility::NotFound, |i| { + FieldVisibility::Found(self.shape.fields[i].flags.visibility()) + }) + } + + fn run_assertions_core(&self, sup_this: SupThis) -> Result<()> { + if let Some(assertion) = &self.assertion { + assertion.0.run(sup_this)?; + } + Ok(()) + } + + fn has_assertion(&self) -> bool { + self.assertion.is_some() + } +} + +pub struct ObjShapeBuilder { + fields: Vec, + next_index: FieldIndex, +} + +impl ObjShapeBuilder { + #[must_use] + pub fn new() -> Self { + Self { + fields: Vec::new(), + next_index: FieldIndex::default(), + } + } + + #[must_use] + pub fn with_capacity(cap: usize) -> Self { + Self { + fields: Vec::with_capacity(cap), + next_index: FieldIndex::default(), + } + } + + pub fn field( + &mut self, + name: impl Into, + visibility: Visibility, + add: bool, + location: Option, + ) -> &mut Self { + let index = self.next_index; + self.next_index = self.next_index.next(); + self.fields.push(ShapeField { + name: name.into(), + flags: ObjFieldFlags::new(add, visibility), + location, + index, + }); + self + } + + #[must_use] + pub fn build(self) -> ObjShape { + ObjShape::new(self.fields) + } +} + +impl Default for ObjShapeBuilder { + fn default() -> Self { + Self::new() + } +} --- a/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@array_comp.jsonnet.snap +++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@array_comp.jsonnet.snap @@ -1,5 +1,6 @@ --- source: crates/jrsonnet-evaluator/src/analyze.rs +assertion_line: 2175 expression: rendered input_file: crates/jrsonnet-evaluator/src/analysis_tests/array_comp.jsonnet --- @@ -26,8 +27,10 @@ ), ), op: Mul, - rhs: Num( - 2.0, + rhs: Trivial( + Num( + 2.0, + ), ), }, compspecs: [ @@ -41,12 +44,8 @@ 0, ), ), - over: Arr { - shape: ClosureShape { - captures: [], - n_locals: 0, - }, - items: [ + over: ArrConst( + [ Num( 1.0, ), @@ -57,7 +56,7 @@ 3.0, ), ], - }, + ), loop_invariant: true, }, If( @@ -70,8 +69,10 @@ ), ), op: Gt, - rhs: Num( - 1.0, + rhs: Trivial( + Num( + 1.0, + ), ), }, ), --- a/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@dollar_deeply_nested.jsonnet.snap +++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@dollar_deeply_nested.jsonnet.snap @@ -20,8 +20,8 @@ --- diagnostics --- --- lir --- Obj( - MemberList( - LObjMembers { + StaticMembers( + LObjStaticMembers { frame_shape: ClosureShape { captures: [], n_locals: 1, @@ -35,74 +35,145 @@ uses_super: false, locals: [], asserts: None, - fields: [ - LFieldMember { - name: Fixed( - "top", - ), - plus: false, - visibility: Normal, - value: ( - ClosureShape { - captures: [], - n_locals: 0, + shape: ObjShape { + fields: [ + ShapeField { + name: "top", + flags: ObjFieldFlags { + add: false, + visibility: Normal, + }, + location: None, + index: FieldIndex( + (), + ), + }, + ShapeField { + name: "a", + flags: ObjFieldFlags { + add: false, + visibility: Normal, }, + location: None, + index: FieldIndex( + (), + ), + }, + ], + }, + bindings: [ + ( + ClosureShape { + captures: [], + n_locals: 0, + }, + Trivial( Str( "outer", ), ), - }, - LFieldMember { - name: Fixed( - "a", - ), - plus: false, - visibility: Normal, - value: ( - ClosureShape { - captures: [], - n_locals: 0, - }, - Obj( - MemberList( - LObjMembers { - frame_shape: ClosureShape { - captures: [ - Local( - LocalSlot( - 0, - ), + ), + ( + ClosureShape { + captures: [], + n_locals: 0, + }, + Obj( + StaticMembers( + LObjStaticMembers { + frame_shape: ClosureShape { + captures: [ + Local( + LocalSlot( + 0, ), - ], - n_locals: 1, - }, - this: None, - set_dollar: false, - uses_super: false, - locals: [], - asserts: None, + ), + ], + n_locals: 1, + }, + this: None, + set_dollar: false, + uses_super: false, + locals: [], + asserts: None, + shape: ObjShape { fields: [ - LFieldMember { - name: Fixed( - "b", + ShapeField { + name: "b", + flags: ObjFieldFlags { + add: false, + visibility: Normal, + }, + location: None, + index: FieldIndex( + (), ), - plus: false, - visibility: Normal, - value: ( - ClosureShape { - captures: [ - Capture( - CaptureSlot( - 0, + }, + ], + }, + bindings: [ + ( + ClosureShape { + captures: [ + Capture( + CaptureSlot( + 0, + ), + ), + ], + n_locals: 0, + }, + Obj( + StaticMembers( + LObjStaticMembers { + frame_shape: ClosureShape { + captures: [ + Capture( + CaptureSlot( + 0, + ), ), + ], + n_locals: 1, + }, + this: Some( + LocalSlot( + 0, ), - ], - n_locals: 0, - }, - Obj( - MemberList( - LObjMembers { - frame_shape: ClosureShape { + ), + set_dollar: false, + uses_super: false, + locals: [], + asserts: None, + shape: ObjShape { + fields: [ + ShapeField { + name: "c", + flags: ObjFieldFlags { + add: false, + visibility: Normal, + }, + location: None, + index: FieldIndex( + (), + ), + }, + ShapeField { + name: "d", + flags: ObjFieldFlags { + add: false, + visibility: Normal, + }, + location: None, + index: FieldIndex( + (), + ), + }, + ], + }, + bindings: [ + ( + ClosureShape { captures: [ Capture( CaptureSlot( @@ -110,86 +181,51 @@ ), ), ], - n_locals: 1, + n_locals: 0, }, - this: Some( - LocalSlot( - 0, - ), - ), - set_dollar: false, - uses_super: false, - locals: [], - asserts: None, - fields: [ - LFieldMember { - name: Fixed( - "c", + Index { + indexable: Slot( + Capture( + CaptureSlot( + 0, + ), ), - plus: false, - visibility: Normal, - value: ( - ClosureShape { - captures: [ - Capture( - CaptureSlot( - 0, - ), - ), - ], - n_locals: 0, - }, - Index { - indexable: Slot( - Capture( - CaptureSlot( - 0, - ), - ), + ), + parts: [ + LIndexPart { + span: virtual::45-48, + value: Trivial( + Str( + "top", ), - parts: [ - LIndexPart { - span: virtual::45-48, - value: Str( - "top", - ), - }, - ], - }, - ), - }, - LFieldMember { - name: Fixed( - "d", - ), - plus: false, - visibility: Normal, - value: ( - ClosureShape { - captures: [], - n_locals: 0, - }, - Slot( - Local( - LocalSlot( - 0, - ), - ), ), + }, + ], + }, + ), + ( + ClosureShape { + captures: [], + n_locals: 0, + }, + Slot( + Local( + LocalSlot( + 0, ), - }, - ], - }, - ), - ), + ), + ), + ), + ], + }, ), - }, - ], - }, - ), + ), + ), + ], + }, ), ), - }, + ), ], }, ), --- a/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@dollar_outside_object.jsonnet.snap +++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@dollar_outside_object.jsonnet.snap @@ -1,5 +1,6 @@ --- source: crates/jrsonnet-evaluator/src/analyze.rs +assertion_line: 2175 expression: rendered input_file: crates/jrsonnet-evaluator/src/analysis_tests/dollar_outside_object.jsonnet --- @@ -21,8 +22,10 @@ parts: [ LIndexPart { span: virtual::2-3, - value: Str( - "a", + value: Trivial( + Str( + "a", + ), ), }, ], --- a/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@function_def.jsonnet.snap +++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@function_def.jsonnet.snap @@ -1,5 +1,6 @@ --- source: crates/jrsonnet-evaluator/src/analyze.rs +assertion_line: 2175 expression: rendered input_file: crates/jrsonnet-evaluator/src/analysis_tests/function_def.jsonnet --- @@ -108,11 +109,15 @@ ), args: LArgsDesc { unnamed: [ - Num( - 1.0, + Trivial( + Num( + 1.0, + ), ), - Num( - 2.0, + Trivial( + Num( + 2.0, + ), ), ], names: [], --- a/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@hoistable_local.jsonnet.snap +++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@hoistable_local.jsonnet.snap @@ -1,5 +1,6 @@ --- source: crates/jrsonnet-evaluator/src/analyze.rs +assertion_line: 2175 expression: rendered input_file: crates/jrsonnet-evaluator/src/analysis_tests/hoistable_local.jsonnet --- @@ -31,8 +32,10 @@ captures: [], n_locals: 0, }, - value: Num( - 1.0, + value: Trivial( + Num( + 1.0, + ), ), }, ], @@ -60,12 +63,16 @@ n_locals: 0, }, value: BinaryOp { - lhs: Num( - 10.0, + lhs: Trivial( + Num( + 10.0, + ), ), op: Add, - rhs: Num( - 20.0, + rhs: Trivial( + Num( + 20.0, + ), ), }, }, --- a/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@ifelse.jsonnet.snap +++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@ifelse.jsonnet.snap @@ -1,7 +1,8 @@ --- source: crates/jrsonnet-evaluator/src/analyze.rs +assertion_line: 2175 expression: rendered -input_file: crates/jrsonnet-evaluator/src/analyze_tests/ifelse.jsonnet +input_file: crates/jrsonnet-evaluator/src/analysis_tests/ifelse.jsonnet --- --- source --- if true then 1 else 2 @@ -12,15 +13,21 @@ --- diagnostics --- --- lir --- IfElse { - cond: Bool( - true, + cond: Trivial( + Bool( + true, + ), ), - cond_then: Num( - 1.0, + cond_then: Trivial( + Num( + 1.0, + ), ), cond_else: Some( - Num( - 2.0, + Trivial( + Num( + 2.0, + ), ), ), } --- a/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@literal.jsonnet.snap +++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@literal.jsonnet.snap @@ -1,7 +1,8 @@ --- source: crates/jrsonnet-evaluator/src/analyze.rs +assertion_line: 2175 expression: rendered -input_file: crates/jrsonnet-evaluator/src/analyze_tests/literal.jsonnet +input_file: crates/jrsonnet-evaluator/src/analysis_tests/literal.jsonnet --- --- source --- 42 @@ -11,6 +12,8 @@ errored: false --- diagnostics --- --- lir --- -Num( - 42.0, +Trivial( + Num( + 42.0, + ), ) --- a/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@loop_invariant.jsonnet.snap +++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@loop_invariant.jsonnet.snap @@ -1,5 +1,6 @@ --- source: crates/jrsonnet-evaluator/src/analyze.rs +assertion_line: 2175 expression: rendered input_file: crates/jrsonnet-evaluator/src/analysis_tests/loop_invariant.jsonnet --- @@ -64,19 +65,25 @@ parts: [ LIndexPart { span: virtual::21-26, - value: Str( - "range", + value: Trivial( + Str( + "range", + ), ), }, ], }, args: LArgsDesc { unnamed: [ - Num( - 1.0, + Trivial( + Num( + 1.0, + ), ), - Num( - 1000.0, + Trivial( + Num( + 1000.0, + ), ), ], names: [], @@ -110,19 +117,25 @@ parts: [ LIndexPart { span: virtual::49-54, - value: Str( - "range", + value: Trivial( + Str( + "range", + ), ), }, ], }, args: LArgsDesc { unnamed: [ - Num( - 1.0, + Trivial( + Num( + 1.0, + ), ), - Num( - 1000.0, + Trivial( + Num( + 1000.0, + ), ), ], names: [], --- a/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@mutual_recursion.jsonnet.snap +++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@mutual_recursion.jsonnet.snap @@ -1,5 +1,6 @@ --- source: crates/jrsonnet-evaluator/src/analyze.rs +assertion_line: 2175 expression: rendered input_file: crates/jrsonnet-evaluator/src/analysis_tests/mutual_recursion.jsonnet --- @@ -46,8 +47,10 @@ captures: [], n_locals: 0, }, - value: Num( - 1.0, + value: Trivial( + Num( + 1.0, + ), ), }, ], @@ -60,8 +63,10 @@ ), ), op: Add, - rhs: Num( - 2.0, + rhs: Trivial( + Num( + 2.0, + ), ), }, }, --- a/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@nested_object_independent.jsonnet.snap +++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@nested_object_independent.jsonnet.snap @@ -17,8 +17,8 @@ --- diagnostics --- --- lir --- Obj( - MemberList( - LObjMembers { + StaticMembers( + LObjStaticMembers { frame_shape: ClosureShape { captures: [], n_locals: 1, @@ -28,103 +28,133 @@ uses_super: false, locals: [], asserts: None, - fields: [ - LFieldMember { - name: Fixed( - "a", - ), - plus: false, - visibility: Normal, - value: ( - ClosureShape { - captures: [], - n_locals: 0, + shape: ObjShape { + fields: [ + ShapeField { + name: "a", + flags: ObjFieldFlags { + add: false, + visibility: Normal, }, + location: None, + index: FieldIndex( + (), + ), + }, + ShapeField { + name: "b", + flags: ObjFieldFlags { + add: false, + visibility: Normal, + }, + location: None, + index: FieldIndex( + (), + ), + }, + ], + }, + bindings: [ + ( + ClosureShape { + captures: [], + n_locals: 0, + }, + Trivial( Num( 1.0, ), ), - }, - LFieldMember { - name: Fixed( - "b", - ), - plus: false, - visibility: Normal, - value: ( - ClosureShape { - captures: [], - n_locals: 0, - }, - Obj( - MemberList( - LObjMembers { - frame_shape: ClosureShape { - captures: [], - n_locals: 1, - }, - this: Some( - LocalSlot( - 0, - ), + ), + ( + ClosureShape { + captures: [], + n_locals: 0, + }, + Obj( + StaticMembers( + LObjStaticMembers { + frame_shape: ClosureShape { + captures: [], + n_locals: 1, + }, + this: Some( + LocalSlot( + 0, ), - set_dollar: false, - uses_super: false, - locals: [], - asserts: None, + ), + set_dollar: false, + uses_super: false, + locals: [], + asserts: None, + shape: ObjShape { fields: [ - LFieldMember { - name: Fixed( - "c", + ShapeField { + name: "c", + flags: ObjFieldFlags { + add: false, + visibility: Normal, + }, + location: None, + index: FieldIndex( + (), ), - plus: false, - visibility: Normal, - value: ( - ClosureShape { - captures: [], - n_locals: 0, - }, - Num( - 2.0, - ), + }, + ShapeField { + name: "d", + flags: ObjFieldFlags { + add: false, + visibility: Normal, + }, + location: None, + index: FieldIndex( + (), ), }, - LFieldMember { - name: Fixed( - "d", + ], + }, + bindings: [ + ( + ClosureShape { + captures: [], + n_locals: 0, + }, + Trivial( + Num( + 2.0, ), - plus: false, - visibility: Normal, - value: ( - ClosureShape { - captures: [], - n_locals: 0, - }, - Index { - indexable: Slot( - Local( - LocalSlot( - 0, - ), + ), + ), + ( + ClosureShape { + captures: [], + n_locals: 0, + }, + Index { + indexable: Slot( + Local( + LocalSlot( + 0, + ), + ), + ), + parts: [ + LIndexPart { + span: virtual::35-36, + value: Trivial( + Str( + "c", ), ), - parts: [ - LIndexPart { - span: virtual::35-36, - value: Str( - "c", - ), - }, - ], }, - ), + ], }, - ], - }, - ), + ), + ], + }, ), ), - }, + ), ], }, ), --- a/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@object_comp.jsonnet.snap +++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@object_comp.jsonnet.snap @@ -1,5 +1,6 @@ --- source: crates/jrsonnet-evaluator/src/analyze.rs +assertion_line: 2175 expression: rendered input_file: crates/jrsonnet-evaluator/src/analysis_tests/object_comp.jsonnet --- @@ -71,12 +72,8 @@ 0, ), ), - over: Arr { - shape: ClosureShape { - captures: [], - n_locals: 0, - }, - items: [ + over: ArrConst( + [ Str( "a", ), @@ -84,7 +81,7 @@ "b", ), ], - }, + ), loop_invariant: true, }, ], --- a/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@object_dollar.jsonnet.snap +++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@object_dollar.jsonnet.snap @@ -12,8 +12,8 @@ --- diagnostics --- --- lir --- Obj( - MemberList( - LObjMembers { + StaticMembers( + LObjStaticMembers { frame_shape: ClosureShape { captures: [], n_locals: 1, @@ -27,95 +27,119 @@ uses_super: false, locals: [], asserts: None, - fields: [ - LFieldMember { - name: Fixed( - "a", - ), - plus: false, - visibility: Normal, - value: ( - ClosureShape { - captures: [], - n_locals: 0, + shape: ObjShape { + fields: [ + ShapeField { + name: "a", + flags: ObjFieldFlags { + add: false, + visibility: Normal, }, + location: None, + index: FieldIndex( + (), + ), + }, + ShapeField { + name: "b", + flags: ObjFieldFlags { + add: false, + visibility: Normal, + }, + location: None, + index: FieldIndex( + (), + ), + }, + ], + }, + bindings: [ + ( + ClosureShape { + captures: [], + n_locals: 0, + }, + Trivial( Num( 1.0, ), ), - }, - LFieldMember { - name: Fixed( - "b", - ), - plus: false, - visibility: Normal, - value: ( - ClosureShape { - captures: [], - n_locals: 0, - }, - Obj( - MemberList( - LObjMembers { - frame_shape: ClosureShape { - captures: [ - Local( - LocalSlot( - 0, - ), + ), + ( + ClosureShape { + captures: [], + n_locals: 0, + }, + Obj( + StaticMembers( + LObjStaticMembers { + frame_shape: ClosureShape { + captures: [ + Local( + LocalSlot( + 0, ), - ], - n_locals: 1, - }, - this: None, - set_dollar: false, - uses_super: false, - locals: [], - asserts: None, + ), + ], + n_locals: 1, + }, + this: None, + set_dollar: false, + uses_super: false, + locals: [], + asserts: None, + shape: ObjShape { fields: [ - LFieldMember { - name: Fixed( - "c", + ShapeField { + name: "c", + flags: ObjFieldFlags { + add: false, + visibility: Normal, + }, + location: None, + index: FieldIndex( + (), ), - plus: false, - visibility: Normal, - value: ( - ClosureShape { - captures: [ - Capture( - CaptureSlot( - 0, - ), - ), - ], - n_locals: 0, - }, - Index { - indexable: Slot( - Capture( - CaptureSlot( - 0, - ), + }, + ], + }, + bindings: [ + ( + ClosureShape { + captures: [ + Capture( + CaptureSlot( + 0, + ), + ), + ], + n_locals: 0, + }, + Index { + indexable: Slot( + Capture( + CaptureSlot( + 0, + ), + ), + ), + parts: [ + LIndexPart { + span: virtual::18-19, + value: Trivial( + Str( + "a", ), ), - parts: [ - LIndexPart { - span: virtual::18-19, - value: Str( - "a", - ), - }, - ], }, - ), + ], }, - ], - }, - ), + ), + ], + }, ), ), - }, + ), ], }, ), --- a/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@object_self.jsonnet.snap +++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@object_self.jsonnet.snap @@ -12,8 +12,8 @@ --- diagnostics --- --- lir --- Obj( - MemberList( - LObjMembers { + StaticMembers( + LObjStaticMembers { frame_shape: ClosureShape { captures: [], n_locals: 1, @@ -27,53 +27,69 @@ uses_super: false, locals: [], asserts: None, - fields: [ - LFieldMember { - name: Fixed( - "a", - ), - plus: false, - visibility: Normal, - value: ( - ClosureShape { - captures: [], - n_locals: 0, + shape: ObjShape { + fields: [ + ShapeField { + name: "a", + flags: ObjFieldFlags { + add: false, + visibility: Normal, + }, + location: None, + index: FieldIndex( + (), + ), + }, + ShapeField { + name: "b", + flags: ObjFieldFlags { + add: false, + visibility: Normal, }, + location: None, + index: FieldIndex( + (), + ), + }, + ], + }, + bindings: [ + ( + ClosureShape { + captures: [], + n_locals: 0, + }, + Trivial( Num( 1.0, ), ), - }, - LFieldMember { - name: Fixed( - "b", - ), - plus: false, - visibility: Normal, - value: ( - ClosureShape { - captures: [], - n_locals: 0, - }, - Index { - indexable: Slot( - Local( - LocalSlot( - 0, - ), + ), + ( + ClosureShape { + captures: [], + n_locals: 0, + }, + Index { + indexable: Slot( + Local( + LocalSlot( + 0, ), ), - parts: [ - LIndexPart { - span: virtual::16-17, - value: Str( + ), + parts: [ + LIndexPart { + span: virtual::16-17, + value: Trivial( + Str( "a", ), - }, - ], - }, - ), - }, + ), + }, + ], + }, + ), ], }, ), --- a/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@object_with_locals.jsonnet.snap +++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@object_with_locals.jsonnet.snap @@ -16,8 +16,8 @@ --- diagnostics --- --- lir --- Obj( - MemberList( - LObjMembers { + StaticMembers( + LObjStaticMembers { frame_shape: ClosureShape { captures: [], n_locals: 2, @@ -36,59 +36,75 @@ captures: [], n_locals: 0, }, - value: Num( - 10.0, + value: Trivial( + Num( + 10.0, + ), ), }, ], asserts: None, - fields: [ - LFieldMember { - name: Fixed( - "a", + shape: ObjShape { + fields: [ + ShapeField { + name: "a", + flags: ObjFieldFlags { + add: false, + visibility: Normal, + }, + location: None, + index: FieldIndex( + (), + ), + }, + ShapeField { + name: "b", + flags: ObjFieldFlags { + add: false, + visibility: Normal, + }, + location: None, + index: FieldIndex( + (), + ), + }, + ], + }, + bindings: [ + ( + ClosureShape { + captures: [], + n_locals: 0, + }, + Slot( + Local( + LocalSlot( + 1, + ), + ), ), - plus: false, - visibility: Normal, - value: ( - ClosureShape { - captures: [], - n_locals: 0, - }, - Slot( + ), + ( + ClosureShape { + captures: [], + n_locals: 0, + }, + BinaryOp { + lhs: Slot( Local( LocalSlot( 1, ), ), ), - ), - }, - LFieldMember { - name: Fixed( - "b", - ), - plus: false, - visibility: Normal, - value: ( - ClosureShape { - captures: [], - n_locals: 0, - }, - BinaryOp { - lhs: Slot( - Local( - LocalSlot( - 1, - ), - ), - ), - op: Mul, - rhs: Num( + op: Mul, + rhs: Trivial( + Num( 2.0, ), - }, - ), - }, + ), + }, + ), ], }, ), --- 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,5 +1,6 @@ --- source: crates/jrsonnet-evaluator/src/analyze.rs +assertion_line: 2175 expression: rendered input_file: crates/jrsonnet-evaluator/src/analysis_tests/redeclared_local.jsonnet --- @@ -31,8 +32,10 @@ captures: [], n_locals: 0, }, - value: Num( - 1.0, + value: Trivial( + Num( + 1.0, + ), ), }, ], --- a/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@shadowing.jsonnet.snap +++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@shadowing.jsonnet.snap @@ -1,5 +1,6 @@ --- source: crates/jrsonnet-evaluator/src/analyze.rs +assertion_line: 2175 expression: rendered input_file: crates/jrsonnet-evaluator/src/analysis_tests/shadowing.jsonnet --- @@ -32,8 +33,10 @@ captures: [], n_locals: 0, }, - value: Num( - 1.0, + value: Trivial( + Num( + 1.0, + ), ), }, ], @@ -54,8 +57,10 @@ captures: [], n_locals: 0, }, - value: Num( - 2.0, + value: Trivial( + Num( + 2.0, + ), ), }, ], --- a/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@simple_local.jsonnet.snap +++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@simple_local.jsonnet.snap @@ -1,5 +1,6 @@ --- source: crates/jrsonnet-evaluator/src/analyze.rs +assertion_line: 2175 expression: rendered input_file: crates/jrsonnet-evaluator/src/analysis_tests/simple_local.jsonnet --- @@ -28,8 +29,10 @@ captures: [], n_locals: 0, }, - value: Num( - 1.0, + value: Trivial( + Num( + 1.0, + ), ), }, ], @@ -42,8 +45,10 @@ ), ), op: Add, - rhs: Num( - 2.0, + rhs: Trivial( + Num( + 2.0, + ), ), }, }, --- a/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@slice.jsonnet.snap +++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@slice.jsonnet.snap @@ -1,6 +1,6 @@ --- source: crates/jrsonnet-evaluator/src/analyze.rs -assertion_line: 2017 +assertion_line: 2175 expression: rendered input_file: crates/jrsonnet-evaluator/src/analysis_tests/slice.jsonnet --- @@ -14,12 +14,8 @@ --- lir --- Slice( LSliceExpr { - value: Arr { - shape: ClosureShape { - captures: [], - n_locals: 0, - }, - items: [ + value: ArrConst( + [ Num( 1.0, ), @@ -36,15 +32,19 @@ 5.0, ), ], - }, + ), start: Some( - Num( - 1.0, + Trivial( + Num( + 1.0, + ), ), ), end: Some( - Num( - 3.0, + Trivial( + Num( + 3.0, + ), ), ), step: None, --- a/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@super_outside_object.jsonnet.snap +++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@super_outside_object.jsonnet.snap @@ -1,5 +1,6 @@ --- source: crates/jrsonnet-evaluator/src/analyze.rs +assertion_line: 2175 expression: rendered input_file: crates/jrsonnet-evaluator/src/analysis_tests/super_outside_object.jsonnet --- @@ -21,8 +22,10 @@ parts: [ LIndexPart { span: virtual::6-7, - value: Str( - "a", + value: Trivial( + Str( + "a", + ), ), }, ], --- a/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@super_usage.jsonnet.snap +++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@super_usage.jsonnet.snap @@ -13,8 +13,8 @@ --- lir --- BinaryOp { lhs: Obj( - MemberList( - LObjMembers { + StaticMembers( + LObjStaticMembers { frame_shape: ClosureShape { captures: [], n_locals: 1, @@ -24,47 +24,63 @@ uses_super: false, locals: [], asserts: None, - fields: [ - LFieldMember { - name: Fixed( - "a", - ), - plus: false, - visibility: Normal, - value: ( - ClosureShape { - captures: [], - n_locals: 0, + shape: ObjShape { + fields: [ + ShapeField { + name: "a", + flags: ObjFieldFlags { + add: false, + visibility: Normal, }, + location: None, + index: FieldIndex( + (), + ), + }, + ShapeField { + name: "b", + flags: ObjFieldFlags { + add: false, + visibility: Normal, + }, + location: None, + index: FieldIndex( + (), + ), + }, + ], + }, + bindings: [ + ( + ClosureShape { + captures: [], + n_locals: 0, + }, + Trivial( Num( 1.0, ), ), - }, - LFieldMember { - name: Fixed( - "b", - ), - plus: false, - visibility: Normal, - value: ( - ClosureShape { - captures: [], - n_locals: 0, - }, + ), + ( + ClosureShape { + captures: [], + n_locals: 0, + }, + Trivial( Num( 2.0, ), ), - }, + ), ], }, ), ), op: Add, rhs: Obj( - MemberList( - LObjMembers { + StaticMembers( + LObjStaticMembers { frame_shape: ClosureShape { captures: [], n_locals: 1, @@ -78,67 +94,85 @@ uses_super: true, locals: [], asserts: None, - fields: [ - LFieldMember { - name: Fixed( - "a", - ), - plus: false, - visibility: Normal, - value: ( - ClosureShape { - captures: [], - n_locals: 0, + shape: ObjShape { + fields: [ + ShapeField { + name: "a", + flags: ObjFieldFlags { + add: false, + visibility: Normal, + }, + location: None, + index: FieldIndex( + (), + ), + }, + ShapeField { + name: "c", + flags: ObjFieldFlags { + add: false, + visibility: Normal, }, - BinaryOp { - lhs: Index { - indexable: Super, - parts: [ - LIndexPart { - span: virtual::28-29, - value: Str( + location: None, + index: FieldIndex( + (), + ), + }, + ], + }, + bindings: [ + ( + ClosureShape { + captures: [], + n_locals: 0, + }, + BinaryOp { + lhs: Index { + indexable: Super, + parts: [ + LIndexPart { + span: virtual::28-29, + value: Trivial( + Str( "a", ), - }, - ], - }, - op: Add, - rhs: Num( + ), + }, + ], + }, + op: Add, + rhs: Trivial( + Num( 10.0, ), - }, - ), - }, - LFieldMember { - name: Fixed( - "c", - ), - plus: false, - visibility: Normal, - value: ( - ClosureShape { - captures: [], - n_locals: 0, - }, - Index { - indexable: Slot( - Local( - LocalSlot( - 0, - ), + ), + }, + ), + ( + ClosureShape { + captures: [], + n_locals: 0, + }, + Index { + indexable: Slot( + Local( + LocalSlot( + 0, ), ), - parts: [ - LIndexPart { - span: virtual::44-45, - value: Str( + ), + parts: [ + LIndexPart { + span: virtual::44-45, + value: Trivial( + Str( "b", ), - }, - ], - }, - ), - }, + ), + }, + ], + }, + ), ], }, ), --- a/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@undefined_var.jsonnet.snap +++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@undefined_var.jsonnet.snap @@ -1,5 +1,6 @@ --- source: crates/jrsonnet-evaluator/src/analyze.rs +assertion_line: 2175 expression: rendered input_file: crates/jrsonnet-evaluator/src/analysis_tests/undefined_var.jsonnet --- @@ -19,7 +20,9 @@ "ref", ), op: Add, - rhs: Num( - 1.0, + rhs: Trivial( + Num( + 1.0, + ), ), } --- a/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@unused_local.jsonnet.snap +++ b/crates/jrsonnet-evaluator/src/snapshots/jrsonnet_evaluator__analyze__tests__snapshots@unused_local.jsonnet.snap @@ -1,5 +1,6 @@ --- source: crates/jrsonnet-evaluator/src/analyze.rs +assertion_line: 2175 expression: rendered input_file: crates/jrsonnet-evaluator/src/analysis_tests/unused_local.jsonnet --- @@ -31,13 +32,17 @@ captures: [], n_locals: 0, }, - value: Num( - 1.0, + value: Trivial( + Num( + 1.0, + ), ), }, ], - body: Num( - 2.0, + body: Trivial( + Num( + 2.0, + ), ), }, ) --- a/crates/jrsonnet-evaluator/src/tla.rs +++ b/crates/jrsonnet-evaluator/src/tla.rs @@ -5,7 +5,7 @@ use jrsonnet_ir::{SourceFifo, SourcePath}; use crate::{ - Result, Thunk, Val, + Result, Thunk, Val, ensure_sufficient_stack, function::{CallLocation, PreparedFuncVal}, in_description_frame, with_state, }; @@ -21,7 +21,7 @@ } impl TlaArg { pub fn evaluate_tailstrict(&self) -> Result { - match self { + ensure_sufficient_stack(|| match self { Self::String(s) => Ok(Val::string(s.clone())), Self::Val(val) => Ok(val.clone()), Self::Lazy(lazy) => Ok(lazy.evaluate()?), @@ -38,7 +38,7 @@ SourcePath::new(SourceFifo("".to_owned(), p.as_bytes().into())); s.import_resolved(resolved) }), - } + }) } pub fn evaluate(&self) -> Result> { match self {