difftreelog
style fix clippy warnings
in: master
30 files changed
bindings/jrsonnet-web/src/lib.rsdiffbeforeafterboth65}65}666667fn unwrap_val_ref(value: &JsValue) -> Result<<WasmVal as RefFromWasmAbi>::Anchor, JsValue> {67fn unwrap_val_ref(value: &JsValue) -> Result<<WasmVal as RefFromWasmAbi>::Anchor, JsValue> {68 #[allow(69 clippy::cast_sign_loss,70 clippy::cast_possible_truncation,71 reason = "defined to be u32"72 )]68 let ptr = get(value, &JsValue::from_str("__wbg_ptr"))73 let ptr = get(value, &JsValue::from_str("__wbg_ptr"))69 .ok()74 .ok()70 .and_then(|v| v.as_f64())75 .and_then(|v| v.as_f64())371impl WasmArrValue {376impl WasmArrValue {372 #[wasm_bindgen(getter)]377 #[wasm_bindgen(getter)]373 pub fn length(&self) -> u32 {378 pub fn length(&self) -> u32 {374 self.arr.len()379 self.arr.len32()375 }380 }376 pub fn at(&self, index: u32) -> Result<Option<WasmVal>, JsValue> {381 pub fn at(&self, index: u32) -> Result<Option<WasmVal>, JsValue> {377 let result = self.state.as_ref().map_or_else(382 let result = self.state.as_ref().map_or_else(378 || self.arr.get(index),383 || self.arr.get32(index),379 |state| {384 |state| {380 let _guard = state.try_enter();385 let _guard = state.try_enter();381 self.arr.get(index)386 self.arr.get32(index)382 },387 },383 );388 );384 result389 resultbindings/jsonnet/src/lib.rsdiffbeforeafterboth66 #[cfg(target_family = "unix")]66 #[cfg(target_family = "unix")]67 {67 {68 use std::os::unix::ffi::OsStrExt;68 use std::os::unix::ffi::OsStrExt;69 let str = CString::new(input.as_os_str().as_bytes()).expect("input has zero byte in it");69 CString::new(input.as_os_str().as_bytes()).expect("input has zero byte in it")70 str71 }70 }72 #[cfg(not(target_family = "unix"))]71 #[cfg(not(target_family = "unix"))]73 {72 {74 let str = input.as_os_str().to_str().expect("bad utf-8");73 let str = input.as_os_str().to_str().expect("bad utf-8");75 let cstr = CString::new(str).expect("input has NUL inside");74 CString::new(str).expect("input has NUL inside")76 cstr77 }75 }78}76}7977cmds/jrb/src/main.rsdiffbeforeafterboth104 }104 }105}105}106106107#[allow(clippy::too_many_lines)]107fn main() {108fn main() {108 tracing_subscriber::fmt().init();109 tracing_subscriber::fmt().init();109110crates/jrsonnet-evaluator/src/analyze.rsdiffbeforeafterboth28use rustc_hash::FxHashMap;28use rustc_hash::FxHashMap;29use smallvec::SmallVec;29use smallvec::SmallVec;303031use crate::error::{format_found, suggest_names};31use crate::{32 arr::arridx,33 error::{format_found, suggest_names},34};323533#[derive(Debug, Clone, Copy)]36#[derive(Debug, Clone, Copy)]34#[must_use]37#[must_use]658 stack: &'s mut AnalysisStack,661 stack: &'s mut AnalysisStack,659 bomb: DropBomb,662 bomb: DropBomb,660}663}661impl<'s> PendingBody<'s> {664impl PendingBody<'_> {662 /// After the body is processed, drop the frame's locals and emit any665 /// After the body is processed, drop the frame's locals and emit any663 /// "unused local" warnings.666 /// "unused local" warnings.664 fn finish(self) {667 fn finish(self) {704 .drain(closures.first_in_frame.idx()..)707 .drain(closures.first_in_frame.idx()..)705 .collect();708 .collect();706 for (i, def) in drained.iter().enumerate().rev() {709 for (i, def) in drained.iter().enumerate().rev() {707 let id = LocalId(closures.first_in_frame.0 + i as u32);710 let id = LocalId(closures.first_in_frame.0 + arridx(i));708 let stack_locals = stack711 let stack_locals = stack709 .local_by_name712 .local_by_name710 .get_mut(&def.name)713 .get_mut(&def.name)819 let (this_refs, rest) = refs.split_at(*refs_len);822 let (this_refs, rest) = refs.split_at(*refs_len);820 refs = rest;823 refs = rest;821 let start = next_id;824 let start = next_id;822 next_id += *dest_count as u32;825 next_id += arridx(*dest_count);823 Closure {826 Closure {824 references: this_refs,827 references: this_refs,825 ids: start..next_id,828 ids: start..next_id,1043 }1046 }104410471045 fn next_local_id(&self) -> LocalId {1048 fn next_local_id(&self) -> LocalId {1046 LocalId(self.local_defs.len() as u32)1049 LocalId(arridx(self.local_defs.len()))1047 }1050 }104810511049 fn report_error(&mut self, msg: impl Into<String>, span: Option<Span>) {1052 fn report_error(&mut self, msg: impl Into<String>, span: Option<Span>) {1565 let mut pending = alloc.finish();1568 let mut pending = alloc.finish();156615691567 let mut l_binds: Vec<LBind> = Vec::with_capacity(binds.len());1570 let mut l_binds: Vec<LBind> = Vec::with_capacity(binds.len());1568 for (bind, destruct) in binds.iter().zip(destructs.into_iter()) {1571 for (bind, destruct) in binds.iter().zip(destructs) {1569 let mut value_taint = AnalysisResult::default();1572 let mut value_taint = AnalysisResult::default();1570 let (value_shape, value) = pending1573 let (value_shape, value) = pending1571 .stack1574 .stack1608 let mut pending = alloc.finish();1611 let mut pending = alloc.finish();160916121610 let mut l_params: Vec<LParam> = Vec::with_capacity(params.exprs.len());1613 let mut l_params: Vec<LParam> = Vec::with_capacity(params.exprs.len());1611 for (p, destruct) in params.exprs.iter().zip(param_destructs.into_iter()) {1614 for (p, destruct) in params.exprs.iter().zip(param_destructs) {1612 let mut value_taint = AnalysisResult::default();1615 let mut value_taint = AnalysisResult::default();1613 let default = p.default.as_ref().map_or_else(1616 let default = p.default.as_ref().map_or_else(1614 || None,1617 || None,crates/jrsonnet-evaluator/src/arr/mod.rsdiffbeforeafterboth2 any::Any,2 any::Any,3 fmt::{self},3 fmt::{self},4 num::NonZeroU32,4 num::NonZeroU32,5 ops::{Bound, RangeBounds},5 rc::Rc,6 rc::Rc,6};7};78104 Self::new(RangeArray::new_inclusive(a, b))105 Self::new(RangeArray::new_inclusive(a, b))105 }106 }106107108 #[inline]107 #[must_use]109 #[must_use]108 pub fn slice(self, index: Option<i32>, end: Option<i32>, step: Option<NonZeroU32>) -> Self {110 pub fn slice(self, range: impl RangeBounds<usize>) -> Self {111 fn map_bound(start: bool, bound: Bound<&usize>) -> Option<i32> {112 match bound {113 Bound::Included(&v) => Some(i32::try_from(v).unwrap_or(i32::MAX)),114 Bound::Excluded(&v) => Some(115 i32::try_from(v)116 .unwrap_or(i32::MAX)117 .saturating_add(if start { 1 } else { -1 }),118 ),119 Bound::Unbounded => None,120 }121 }122 self.slice32(123 map_bound(true, range.start_bound()),124 map_bound(false, range.end_bound()),125 None,126 )127 }128129 #[must_use]130 pub fn slice32(self, index: Option<i32>, end: Option<i32>, step: Option<NonZeroU32>) -> Self {109 let get_idx = |pos: Option<i32>, len: u32, default| match pos {131 let get_idx = |pos: Option<i32>, len: u32, default| match pos {110 #[expect(111 clippy::cast_sign_loss,112 reason = "abs value is used, len is limited to u31"113 )]114 Some(v) if v < 0 => len.saturating_add_signed(v),132 Some(v) if v < 0 => len.saturating_add_signed(v),115 #[expect(clippy::cast_sign_loss, reason = "abs value is used")]133 #[expect(clippy::cast_sign_loss, reason = "abs value is used")]116 Some(v) => (v as u32).min(len),134 Some(v) => (v as u32).min(len),117 None => default,135 None => default,118 };136 };119 let index = get_idx(index, self.len(), 0);137 let index = get_idx(index, self.len32(), 0);120 let end = get_idx(end, self.len(), self.len());138 let end = get_idx(end, self.len32(), self.len32());121 let step = step.unwrap_or_else(|| NonZeroU32::new(1).expect("1 != 0"));139 let step = step.unwrap_or_else(|| NonZeroU32::new(1).expect("1 != 0"));122140123 if index >= end {141 if index >= end {126144127 Self::new(SliceArray {145 Self::new(SliceArray {128 inner: self,146 inner: self,129 #[expect(clippy::cast_possible_truncation, reason = "len is limited to u31")]130 from: index as u32,147 from: index,131 #[expect(clippy::cast_possible_truncation, reason = "len is limited to u31")]132 to: end as u32,148 to: end,133 step: step.get(),149 step: step.get(),134 })150 })135 }151 }136152137 /// Array length.153 /// Array length.154 #[inline]138 pub fn len(&self) -> u32 {155 pub fn len32(&self) -> u32 {139 self.0.len()156 self.0.len32()140 }157 }158159 pub fn len(&self) -> usize {160 self.len32() as usize161 }141162142 /// Is array contains no elements?163 /// Is array contains no elements?164 #[inline]143 pub fn is_empty(&self) -> bool {165 pub fn is_empty(&self) -> bool {144 self.0.is_empty()166 self.0.is_empty()145 }167 }146168169 #[inline]147 pub fn is_cheap(&self) -> bool {170 pub fn is_cheap(&self) -> bool {148 self.0.is_cheap()171 self.0.is_cheap()149 }172 }150173151 /// Get array element by index, evaluating it, if it is lazy.174 /// Get array element by index, evaluating it, if it is lazy.152 ///175 ///153 /// Returns `None` on out-of-bounds condition.176 /// Returns `None` on out-of-bounds condition.177 #[inline]154 pub fn get(&self, index: u32) -> Result<Option<Val>> {178 pub fn get32(&self, index: u32) -> Result<Option<Val>> {155 self.0.get(index)179 self.0.get32(index)156 }180 }181182 pub fn get(&self, index: usize) -> Result<Option<Val>> {183 let Ok(i) = u32::try_from(index) else {184 return Ok(None);185 };186 self.get32(i)187 }157188158 /// Get array element by index, without evaluation.189 /// Get array element by index, without evaluation.159 ///190 ///160 /// Returns `None` on out-of-bounds condition.191 /// Returns `None` on out-of-bounds condition.192 #[inline]161 pub fn get_lazy(&self, index: u32) -> Option<Thunk<Val>> {193 pub fn get_lazy32(&self, index: u32) -> Option<Thunk<Val>> {162 self.0.get_lazy(index)194 self.0.get_lazy32(index)163 }195 }196197 pub fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {198 u32::try_from(index).ok().and_then(|i| self.get_lazy32(i))199 }164200165 pub fn iter(&self) -> impl ArrayLikeIter<Result<Val>> + '_ {201 pub fn iter(&self) -> impl ArrayLikeIter<Result<Val>> + '_ {166 (0..self.len()).map(|i| self.get(i).transpose().expect("length checked"))202 (0..self.len32()).map(|i| self.get32(i).transpose().expect("length checked"))167 }203 }168204169 /// Iterate over elements, returning lazy values.205 /// Iterate over elements, returning lazy values.170 pub fn iter_lazy(&self) -> impl ArrayLikeIter<Thunk<Val>> + '_ {206 pub fn iter_lazy(&self) -> impl ArrayLikeIter<Thunk<Val>> + '_ {171 (0..self.len()).map(|i| self.get_lazy(i).expect("length checked"))207 (0..self.len32()).map(|i| self.get_lazy32(i).expect("length checked"))172 }208 }173209174 /// Return a reversed view on current array.210 /// Return a reversed view on current array.202 }238 }203}239}240241/// Checks that the usize does not exceed 4g with debug assertions enabled242/// Should only be used on values that can't reasonably exceed this value243#[inline]244pub(crate) fn arridx(i: usize) -> u32 {245 #[allow(246 clippy::cast_possible_truncation,247 reason = "array indexes never exceed 4g"248 )]249 if cfg!(debug_assertions) {250 u32::try_from(i).expect("4g hard limit")251 } else {252 i as u32253 }254}204255crates/jrsonnet-evaluator/src/arr/spec.rsdiffbeforeafterboth9use jrsonnet_gcmodule::{Cc, Trace};9use jrsonnet_gcmodule::{Cc, Trace};10use jrsonnet_interner::{IBytes, IStr};10use jrsonnet_interner::{IBytes, IStr};111112use super::ArrValue;12use super::{ArrValue, arridx};13use crate::{13use crate::{14 Context, Error, ObjValue, Result, Thunk, Val,14 Context, Error, ObjValue, Result, Thunk, Val,15 analyze::{ClosureShape, LExpr},15 analyze::{ClosureShape, LExpr},21};21};222223pub trait ArrayLike: Any + Trace + Debug {23pub trait ArrayLike: Any + Trace + Debug {24 fn len(&self) -> u32;24 fn len32(&self) -> u32;25 fn is_empty(&self) -> bool {25 fn is_empty(&self) -> bool {26 self.len() == 026 self.len32() == 027 }27 }28 fn get(&self, index: u32) -> Result<Option<Val>>;28 fn get32(&self, index: u32) -> Result<Option<Val>>;29 fn get_lazy(&self, index: u32) -> Option<Thunk<Val>>;29 fn get_lazy32(&self, index: u32) -> Option<Thunk<Val>>;303031 fn is_cheap(&self) -> bool {31 fn is_cheap(&self) -> bool {32 false32 false40where40where41 T: Any + Trace + Debug + ArrayCheap,41 T: Any + Trace + Debug + ArrayCheap,42{42{43 fn len(&self) -> u32 {43 fn len32(&self) -> u32 {44 <T as ArrayCheap>::len(self)44 <T as ArrayCheap>::len(self)45 }45 }464647 fn get(&self, index: u32) -> Result<Option<Val>> {47 fn get32(&self, index: u32) -> Result<Option<Val>> {48 Ok(<T as ArrayCheap>::get(self, index))48 Ok(<T as ArrayCheap>::get(self, index))49 }49 }505051 fn get_lazy(&self, index: u32) -> Option<Thunk<Val>> {51 fn get_lazy32(&self, index: u32) -> Option<Thunk<Val>> {52 <T as ArrayCheap>::get(self, index).map(Thunk::evaluated)52 <T as ArrayCheap>::get(self, index).map(Thunk::evaluated)53 }53 }545480 }80 }81}81}82impl ArrayLike for SliceArray {82impl ArrayLike for SliceArray {83 fn len(&self) -> u32 {83 fn len32(&self) -> u32 {84 (self.to - self.from).div_ceil(self.step)84 (self.to - self.from).div_ceil(self.step)85 }85 }868687 fn get(&self, index: u32) -> Result<Option<Val>> {87 fn get32(&self, index: u32) -> Result<Option<Val>> {88 self.inner.get(self.map_idx(index))88 self.inner.get32(self.map_idx(index))89 }89 }909091 fn get_lazy(&self, index: u32) -> Option<Thunk<Val>> {91 fn get_lazy32(&self, index: u32) -> Option<Thunk<Val>> {92 self.inner.get_lazy(self.map_idx(index))92 self.inner.get_lazy32(self.map_idx(index))93 }93 }949495 fn is_cheap(&self) -> bool {95 fn is_cheap(&self) -> bool {9999100impl ArrayCheap for IBytes {100impl ArrayCheap for IBytes {101 fn len(&self) -> u32 {101 fn len(&self) -> u32 {102 self.as_slice().len() as u32102 arridx(self.as_slice().len())103 }103 }104 fn get(&self, index: u32) -> Option<Val> {104 fn get(&self, index: u32) -> Option<Val> {105 self.as_slice()105 self.as_slice()132 }132 }133}133}134impl ArrayLike for ExprArray {134impl ArrayLike for ExprArray {135 fn len(&self) -> u32 {135 fn len32(&self) -> u32 {136 self.cached.borrow().len() as u32136 arridx(self.cached.borrow().len())137 }137 }138 fn get(&self, index: u32) -> Result<Option<Val>> {138 fn get32(&self, index: u32) -> Result<Option<Val>> {139 if index >= self.len() {139 if index >= self.len32() {140 return Ok(None);140 return Ok(None);141 }141 }142 match &self.cached.borrow()[index as usize] {142 match &self.cached.borrow()[index as usize] {157 self.cached.borrow_mut()[index as usize] = ArrayThunk::Computed(new_value.clone());157 self.cached.borrow_mut()[index as usize] = ArrayThunk::Computed(new_value.clone());158 Ok(Some(new_value))158 Ok(Some(new_value))159 }159 }160 fn get_lazy(&self, index: u32) -> Option<Thunk<Val>> {160 fn get_lazy32(&self, index: u32) -> Option<Thunk<Val>> {161 #[derive(Trace)]161 #[derive(Trace)]162 struct ExprArrThunk {162 struct ExprArrThunk {163 expr: ExprArray,163 expr: ExprArray,168168169 fn get(&self) -> Result<Self::Output> {169 fn get(&self) -> Result<Self::Output> {170 self.expr170 self.expr171 .get(self.index)171 .get32(self.index)172 .transpose()172 .transpose()173 .expect("index checked")173 .expect("index checked")174 }174 }175 }175 }176176177 if index >= self.len() {177 if index >= self.len32() {178 return None;178 return None;179 }179 }180 match &self.cached.borrow()[index as usize] {180 match &self.cached.borrow()[index as usize] {202}202}203impl ExtendedArray {203impl ExtendedArray {204 pub fn new(a: ArrValue, b: ArrValue) -> Option<Self> {204 pub fn new(a: ArrValue, b: ArrValue) -> Option<Self> {205 let a_len = a.len();205 let a_len = a.len32();206 let b_len = b.len();206 let b_len = b.len32();207 let len = a_len.checked_add(b_len)?;207 let len = a_len.checked_add(b_len)?;208 Some(Self {208 Some(Self {209 a,209 a,251 }251 }252}252}253impl ArrayLike for ExtendedArray {253impl ArrayLike for ExtendedArray {254 fn get(&self, index: u32) -> Result<Option<Val>> {254 fn get32(&self, index: u32) -> Result<Option<Val>> {255 if self.split > index {255 if self.split > index {256 self.a.get(index)256 self.a.get32(index)257 } else {257 } else {258 self.b.get(index - self.split)258 self.b.get32(index - self.split)259 }259 }260 }260 }261 fn get_lazy(&self, index: u32) -> Option<Thunk<Val>> {261 fn get_lazy32(&self, index: u32) -> Option<Thunk<Val>> {262 if self.split > index {262 if self.split > index {263 self.a.get_lazy(index)263 self.a.get_lazy32(index)264 } else {264 } else {265 self.b.get_lazy(index - self.split)265 self.b.get_lazy32(index - self.split)266 }266 }267 }267 }268268269 fn len(&self) -> u32 {269 fn len32(&self) -> u32 {270 self.len270 self.len271 }271 }272272280 T: IntoUntyped + Trace + fmt::Debug,280 T: IntoUntyped + Trace + fmt::Debug,281 for<'a> &'a T: IntoUntyped,281 for<'a> &'a T: IntoUntyped,282{282{283 fn len(&self) -> u32 {283 fn len32(&self) -> u32 {284 self.as_slice().len().try_into().unwrap_or(u32::MAX)284 self.as_slice().len().try_into().unwrap_or(u32::MAX)285 }285 }286286287 fn get(&self, index: u32) -> Result<Option<Val>> {287 fn get32(&self, index: u32) -> Result<Option<Val>> {288 let Some(elem) = self.as_slice().get(index as usize) else {288 let Some(elem) = self.as_slice().get(index as usize) else {289 return Ok(None);289 return Ok(None);290 };290 };291 IntoUntyped::into_untyped(elem).map(Some)291 IntoUntyped::into_untyped(elem).map(Some)292 }292 }293293294 fn get_lazy(&self, index: u32) -> Option<Thunk<Val>> {294 fn get_lazy32(&self, index: u32) -> Option<Thunk<Val>> {295 let elem = self.as_slice().get(index as usize)?;295 let elem = self.as_slice().get(index as usize)?;296 Some(IntoUntyped::into_lazy_untyped(elem))296 Some(IntoUntyped::into_lazy_untyped(elem))297 }297 }343#[derive(Debug, Trace)]343#[derive(Debug, Trace)]344pub struct ReverseArray(pub ArrValue);344pub struct ReverseArray(pub ArrValue);345impl ArrayLike for ReverseArray {345impl ArrayLike for ReverseArray {346 fn len(&self) -> u32 {346 fn len32(&self) -> u32 {347 self.0.len()347 self.0.len32()348 }348 }349349350 fn get(&self, index: u32) -> Result<Option<Val>> {350 fn get32(&self, index: u32) -> Result<Option<Val>> {351 self.0.get(self.0.len() - index - 1)351 self.0.get32(self.0.len32() - index - 1)352 }352 }353353354 fn get_lazy(&self, index: u32) -> Option<Thunk<Val>> {354 fn get_lazy32(&self, index: u32) -> Option<Thunk<Val>> {355 self.0.get_lazy(self.0.len() - index - 1)355 self.0.get_lazy32(self.0.len32() - index - 1)356 }356 }357357358 fn is_cheap(&self) -> bool {358 fn is_cheap(&self) -> bool {374}374}375impl MappedArray {375impl MappedArray {376 pub fn new(inner: ArrValue, mapper: ArrayMapper) -> Self {376 pub fn new(inner: ArrValue, mapper: ArrayMapper) -> Self {377 let len = inner.len();377 let len = inner.len32();378 Self {378 Self {379 inner,379 inner,380 cached: Cc::new(RefCell::new(vec![ArrayThunk::Waiting; len as usize])),380 cached: Cc::new(RefCell::new(vec![ArrayThunk::Waiting; len as usize])),389 }389 }390}390}391impl ArrayLike for MappedArray {391impl ArrayLike for MappedArray {392 fn len(&self) -> u32 {392 fn len32(&self) -> u32 {393 self.cached.borrow().len() as u32393 arridx(self.cached.borrow().len())394 }394 }395395396 fn get(&self, index: u32) -> Result<Option<Val>> {396 fn get32(&self, index: u32) -> Result<Option<Val>> {397 if index >= self.len() {397 if index >= self.len32() {398 return Ok(None);398 return Ok(None);399 }399 }400 match &self.cached.borrow()[index as usize] {400 match &self.cached.borrow()[index as usize] {413413414 let val = self414 let val = self415 .inner415 .inner416 .get(index)416 .get32(index)417 .transpose()417 .transpose()418 .expect("index checked")418 .expect("index checked")419 .and_then(|r| self.evaluate(index, r));419 .and_then(|r| self.evaluate(index, r));428 self.cached.borrow_mut()[index as usize] = ArrayThunk::Computed(new_value.clone());428 self.cached.borrow_mut()[index as usize] = ArrayThunk::Computed(new_value.clone());429 Ok(Some(new_value))429 Ok(Some(new_value))430 }430 }431 fn get_lazy(&self, index: u32) -> Option<Thunk<Val>> {431 fn get_lazy32(&self, index: u32) -> Option<Thunk<Val>> {432 #[derive(Trace)]432 #[derive(Trace)]433 struct MappedArrayThunk {433 struct MappedArrayThunk {434 arr: MappedArray,434 arr: MappedArray,438 type Output = Val;438 type Output = Val;439439440 fn get(&self) -> Result<Self::Output> {440 fn get(&self) -> Result<Self::Output> {441 self.arr.get(self.index).transpose().expect("index checked")441 self.arr442 .get32(self.index)443 .transpose()444 .expect("index checked")442 }445 }443 }446 }444447445 if index >= self.len() {448 if index >= self.len32() {446 return None;449 return None;447 }450 }448 match &self.cached.borrow()[index as usize] {451 match &self.cached.borrow()[index as usize] {471 }474 }472}475}473impl ArrayLike for MakeArray {476impl ArrayLike for MakeArray {474 fn len(&self) -> u32 {477 fn len32(&self) -> u32 {475 self.cached.borrow().len() as u32478 arridx(self.cached.borrow().len())476 }479 }477480478 fn get(&self, index: u32) -> Result<Option<Val>> {481 fn get32(&self, index: u32) -> Result<Option<Val>> {479 if index >= self.len() {482 if index >= self.len32() {480 return Ok(None);483 return Ok(None);481 }484 }482 match &self.cached.borrow()[index as usize] {485 match &self.cached.borrow()[index as usize] {493 unreachable!()496 unreachable!()494 };497 };495498496 let val = self.mapper.call(index as u32);499 let val = self.mapper.call(index);497500498 let new_value = match val {501 let new_value = match val {499 Ok(v) => v,502 Ok(v) => v,505 self.cached.borrow_mut()[index as usize] = ArrayThunk::Computed(new_value.clone());508 self.cached.borrow_mut()[index as usize] = ArrayThunk::Computed(new_value.clone());506 Ok(Some(new_value))509 Ok(Some(new_value))507 }510 }508 fn get_lazy(&self, index: u32) -> Option<Thunk<Val>> {511 fn get_lazy32(&self, index: u32) -> Option<Thunk<Val>> {509 #[derive(Trace)]512 #[derive(Trace)]510 struct MakeArrayThunk {513 struct MakeArrayThunk {511 arr: MakeArray,514 arr: MakeArray,515 type Output = Val;518 type Output = Val;516519517 fn get(&self) -> Result<Self::Output> {520 fn get(&self) -> Result<Self::Output> {518 self.arr.get(self.index).transpose().expect("index checked")521 self.arr522 .get32(self.index)523 .transpose()524 .expect("index checked")519 }525 }520 }526 }521527522 if index >= self.len() {528 if index >= self.len32() {523 return None;529 return None;524 }530 }525 match &self.cached.borrow()[index as usize] {531 match &self.cached.borrow()[index as usize] {543}549}544impl RepeatedArray {550impl RepeatedArray {545 pub fn new(data: ArrValue, repeats: u32) -> Option<Self> {551 pub fn new(data: ArrValue, repeats: u32) -> Option<Self> {546 let total_len = data.len().checked_mul(repeats)?;552 let total_len = data.len32().checked_mul(repeats)?;547 Some(Self {553 Some(Self {548 data,554 data,549 repeats,555 repeats,554 if index > self.total_len {560 if index > self.total_len {555 return None;561 return None;556 }562 }557 Some(index % self.data.len())563 Some(index % self.data.len32())558 }564 }559}565}560566561impl ArrayLike for RepeatedArray {567impl ArrayLike for RepeatedArray {562 fn len(&self) -> u32 {568 fn len32(&self) -> u32 {563 self.total_len569 self.total_len564 }570 }565571566 fn get(&self, index: u32) -> Result<Option<Val>> {572 fn get32(&self, index: u32) -> Result<Option<Val>> {567 let Some(idx) = self.map_idx(index) else {573 let Some(idx) = self.map_idx(index) else {568 return Ok(None);574 return Ok(None);569 };575 };570 self.data.get(idx)576 self.data.get32(idx)571 }577 }572578573 fn get_lazy(&self, index: u32) -> Option<Thunk<Val>> {579 fn get_lazy32(&self, index: u32) -> Option<Thunk<Val>> {574 let idx = self.map_idx(index)?;580 let idx = self.map_idx(index)?;575 self.data.get_lazy(idx)581 self.data.get_lazy32(idx)576 }582 }577583578 fn is_cheap(&self) -> bool {584 fn is_cheap(&self) -> bool {593}599}594600595impl ArrayLike for PickObjectValues {601impl ArrayLike for PickObjectValues {596 fn len(&self) -> u32 {602 fn len32(&self) -> u32 {597 self.keys.len() as u32603 arridx(self.keys.len())598 }604 }599605600 fn get(&self, index: u32) -> Result<Option<Val>> {606 fn get32(&self, index: u32) -> Result<Option<Val>> {601 let Some(key) = self.keys.as_slice().get(index as usize) else {607 let Some(key) = self.keys.as_slice().get(index as usize) else {602 return Ok(None);608 return Ok(None);603 };609 };604 Ok(Some(self.obj.get_or_bail(key.clone())?))610 Ok(Some(self.obj.get_or_bail(key.clone())?))605 }611 }606612607 fn get_lazy(&self, index: u32) -> Option<Thunk<Val>> {613 fn get_lazy32(&self, index: u32) -> Option<Thunk<Val>> {608 let key = self.keys.as_slice().get(index as usize)?;614 let key = self.keys.as_slice().get(index as usize)?;609 Some(self.obj.get_lazy_or_bail(key.clone()))615 Some(self.obj.get_lazy_or_bail(key.clone()))610 }616 }633}639}634640635impl ArrayLike for PickObjectKeyValues {641impl ArrayLike for PickObjectKeyValues {636 fn len(&self) -> u32 {642 fn len32(&self) -> u32 {637 self.keys.len() as u32643 arridx(self.keys.len())638 }644 }639645640 fn get(&self, index: u32) -> Result<Option<Val>> {646 fn get32(&self, index: u32) -> Result<Option<Val>> {641 let Some(key) = self.keys.as_slice().get(index as usize) else {647 let Some(key) = self.keys.as_slice().get(index as usize) else {642 return Ok(None);648 return Ok(None);643 };649 };650 ))656 ))651 }657 }652658653 fn get_lazy(&self, index: u32) -> Option<Thunk<Val>> {659 fn get_lazy32(&self, index: u32) -> Option<Thunk<Val>> {654 let key = self.keys.as_slice().get(index as usize)?;660 let key = self.keys.as_slice().get(index as usize)?;655 // Nothing can fail in the key part, yet value is still661 // Nothing can fail in the key part, yet value is still656 // lazy-evaluated662 // lazy-evaluatedcrates/jrsonnet-evaluator/src/ctx.rsdiffbeforeafterboth122 pub fn enter(self, sup_this: SupThis, build: impl FnOnce(&LocalsFrame, &Context)) -> Context {122 pub fn enter(self, sup_this: SupThis, build: impl FnOnce(&LocalsFrame, &Context)) -> Context {123 let locals = LocalsFrame::new_once(self.n_locals);123 let locals = LocalsFrame::new_once(self.n_locals);124 let val = Context(Cc::new(ContextInternal {124 let val = Context(Cc::new(ContextInternal {125 captures: self.captures.clone(),125 captures: self.captures,126 locals,126 locals,127 sup_this: Some(sup_this),127 sup_this: Some(sup_this),128 }));128 }));crates/jrsonnet-evaluator/src/evaluate/compspec.rsdiffbeforeafterboth97 let value_ctx = inner_ctx97 let value_ctx = inner_ctx98 .pack_captures_sup_this(self.frame_shape)98 .pack_captures_sup_this(self.frame_shape)99 .enter(|fill, ctx| {99 .enter(|fill, ctx| {100 fill_letrec_binds(fill, &ctx, self.locals);100 fill_letrec_binds(fill, ctx, self.locals);101 });101 });102 evaluate_field_member_static(self.builder, inner_ctx, value_ctx, self.field)102 evaluate_field_member_static(self.builder, inner_ctx, value_ctx, self.field)103 }103 }336 Ok(())336 Ok(())337}337}338338339#[allow(clippy::too_many_lines)]339fn evaluate_compspecs(340fn evaluate_compspecs(340 ctx: Context,341 ctx: Context,341 specs: &[LCompSpec],342 specs: &[LCompSpec],381 for (i, item) in arr.iter().enumerate() {382 for (i, item) in arr.iter().enumerate() {382 let item = item?;383 let item = item?;383 let inner_ctx = ctx.pack_captures_sup_this(frame_shape).enter(|fill, ctx| {384 let inner_ctx = ctx.pack_captures_sup_this(frame_shape).enter(|fill, ctx| {384 destruct(dst, fill, Thunk::evaluated(item), &ctx);385 destruct(dst, fill, Thunk::evaluated(item), ctx);385 });386 });386 evaluate_compspecs(387 evaluate_compspecs(387 inner_ctx,388 inner_ctx,crates/jrsonnet-evaluator/src/evaluate/destructure.rsdiffbeforeafterboth5use crate::{5use crate::{6 Context, LocalsFrame, PackedContext, Result, SupThis, Thunk, Unbound, Val,6 Context, LocalsFrame, PackedContext, Result, SupThis, Thunk, Unbound, Val,7 analyze::{7 analyze::{8 ClosureShape, LBind, LDestruct, LDestructField, LDestructRest, LExpr, LLocalExpr, LocalSlot,8 ClosureShape, LBind, LDestruct, LDestructField, LDestructRest, LLocalExpr, LocalSlot,9 },9 },10 bail,10 bail,11 evaluate::evaluate,11 evaluate::evaluate,191920 fill: &LocalsFrame,20 fill: &LocalsFrame,21 value: Thunk<Val>,21 value: Thunk<Val>,22 a_ctx: &Context,22 ctx: &Context,23) {23) {24 let min_len = start.len() + end.len();24 let min_len = start.len() + end.len();25 let has_rest = rest.is_some();25 let has_rest = rest.is_some();29 bail!("expected array");29 bail!("expected array");30 };30 };31 if !has_rest {31 if !has_rest {32 if arr.len() as usize != min_len {32 if arr.len() != min_len {33 bail!("expected {} elements, got {}", min_len, arr.len())33 bail!("expected {} elements, got {}", min_len, arr.len32())34 }34 }35 } else if (arr.len() as usize) < min_len {35 } else if arr.len() < min_len {36 bail!(36 bail!(37 "expected at least {} elements, but array was only {}",37 "expected at least {} elements, but array was only {}",38 min_len,38 min_len,39 arr.len()39 arr.len32()40 )40 )41 }41 }42 Ok(arr)42 Ok(arr)47 destruct(47 destruct(48 d,48 d,49 fill,49 fill,50 Thunk!(move || Ok(full.evaluate()?.get(i as u32)?.expect("length is checked"))),50 Thunk!(move || Ok(full.evaluate()?.get(i)?.expect("length is checked"))),51 a_ctx,51 ctx,52 );52 );53 }53 }545455 let start_len = start.len() as u32;55 let start_len = start.len();56 let end_len = end.len() as u32;56 let end_len = end.len();575758 if let Some(LDestructRest::Keep(slot)) = rest {58 if let Some(LDestructRest::Keep(slot)) = rest {59 let full = full.clone();59 let full = full.clone();62 Thunk!(move || {62 Thunk!(move || {63 let full = full.evaluate()?;63 let full = full.evaluate()?;64 let to = full.len() - end_len;64 let to = full.len() - end_len;65 Ok(Val::Arr(full.slice(65 Ok(Val::Arr(full.slice(start_len..to)))66 Some(start_len as i32),67 Some(to as i32),68 None,69 )))70 }),66 }),71 );67 );79 Thunk!(move || {75 Thunk!(move || {80 let full = full.evaluate()?;76 let full = full.evaluate()?;81 Ok(full77 Ok(full82 .get(full.len() - end_len + i as u32)?78 .get(full.len() - end_len + i)?83 .expect("length is checked"))79 .expect("length is checked"))84 }),80 }),85 a_ctx,81 ctx,86 );82 );87 }83 }88}84}949095 fill: &LocalsFrame,91 fill: &LocalsFrame,96 value: Thunk<Val>,92 value: Thunk<Val>,97 a_ctx: &Context,93 ctx: &Context,98) {94) {99 use jrsonnet_interner::IStr;95 use jrsonnet_interner::IStr;100 use rustc_hash::FxHashSet;96 use rustc_hash::FxHashSet;118 }114 }119 }115 }120 if !has_rest {116 if !has_rest {121 let len = obj.len();117 let len = obj.len32();122 if len as usize > field_names.len() {118 if len as usize > field_names.len() {123 bail!("too many fields, and rest not found");119 bail!("too many fields, and rest not found");124 }120 }142138143 for field in fields {139 for field in fields {144 let field_name = field.name.clone();140 let field_name = field.name.clone();145 let default_thunk: Option<Thunk<Val>> = field141 let default_thunk: Option<Thunk<Val>> = field.default.as_ref().map(|(shape, expr)| {146 .default147 .as_ref()148 .map(|(shape, expr)| build_b_thunk(a_ctx, shape, expr.clone()));142 let expr = expr.clone();143 let env = Context::enter_using(ctx, shape);144 Thunk!(move || evaluate(env, &expr))145 });149146150 let field_full = full.clone();147 let field_full = full.clone();151 let value_thunk = Thunk!(move || {148 let value_thunk = Thunk!(move || {157 });154 });158155159 if let Some(into) = &field.into {156 if let Some(into) = &field.into {160 destruct(into, fill, value_thunk, a_ctx);157 destruct(into, fill, value_thunk, ctx);161 } else {158 } else {162 unreachable!("analyzer lowers object-destruct shorthands into `into`");159 unreachable!("analyzer lowers object-destruct shorthands into `into`");163 }160 }179 }176 }180}177}181182pub fn build_b_thunk(a_ctx: &Context, shape: &ClosureShape, expr: Rc<LExpr>) -> Thunk<Val> {183 let env = Context::enter_using(a_ctx, shape);184 Thunk!(move || evaluate(env, &expr))185}186pub fn build_b_thunk_uno(a_ctx: &Context, shape: Rc<(ClosureShape, LExpr)>) -> Thunk<Val> {187 let env = Context::enter_using(a_ctx, &shape.0);188 Thunk!(move || evaluate(env, &shape.1))189}190178191pub fn fill_letrec_binds(fill: &LocalsFrame, ctx: &Context, binds: &[LBind]) {179pub fn fill_letrec_binds(fill: &LocalsFrame, ctx: &Context, binds: &[LBind]) {192 for bind in binds {180 for bind in binds {181 let expr = bind.value.clone();193 let value_thunk = build_b_thunk(ctx, &bind.value_shape, bind.value.clone());182 let env = Context::enter_using(ctx, &bind.value_shape);194 destruct(&bind.destruct, fill, value_thunk, ctx);183 destruct(184 &bind.destruct,185 fill,186 Thunk!(move || evaluate(env, &expr)),187 ctx,188 );195 }189 }196}190}crates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth778use self::{8use self::{9 compspec::{evaluate_arr_comp, evaluate_obj_comp},9 compspec::{evaluate_arr_comp, evaluate_obj_comp},10 destructure::{build_b_thunk_uno, evaluate_local_expr, evaluate_locals_unbound},10 destructure::{evaluate_local_expr, evaluate_locals_unbound},11 operator::evaluate_binary_op_special,11 operator::evaluate_binary_op_special,12};12};13use crate::{13use crate::{115 }115 }116}116}117117118#[allow(clippy::too_many_lines)]118pub fn evaluate(ctx: Context, expr: &LExpr) -> Result<Val> {119pub fn evaluate(ctx: Context, expr: &LExpr) -> Result<Val> {119 Ok(match expr {120 Ok(match expr {120 LExpr::Null => Val::Null,121 LExpr::Null => Val::Null,218 BoundedUsize::from_untyped(v).description("slice step value")219 BoundedUsize::from_untyped(v).description("slice step value")219 })220 })220 .transpose()?;221 .transpose()?;221 Val::from(indexable.slice(start, end, step)?)222 Val::from(indexable.slice32(start, end, step)?)222 }223 }223 LExpr::Super => Val::Obj(ctx.try_sup_this()?.standalone_super().ok_or(NoSuperFound)?),224 LExpr::Super => Val::Obj(ctx.try_sup_this()?.standalone_super().ok_or(NoSuperFound)?),224 LExpr::Import {225 LExpr::Import {320 )321 )321}322}322323324#[allow(clippy::too_many_lines)]323fn evaluate_index(ctx: Context, indexable: &LExpr, parts: &[LIndexPart]) -> Result<Val> {325fn evaluate_index(ctx: Context, indexable: &LExpr, parts: &[LIndexPart]) -> Result<Val> {324 let mut parts = parts.iter();326 let mut parts = parts.iter();325 let mut indexable = if matches!(indexable, LExpr::Super) {327 let mut indexable = if matches!(indexable, LExpr::Super) {394 if n.fract() > f64::EPSILON {396 if n.fract() > f64::EPSILON {395 bail!(FractionalIndex)397 bail!(FractionalIndex)396 }398 }397 let len = arr.len();399 let len = arr.len32();398 if n < 0.0 || n > f64::from(len) {400 if n < 0.0 || n > f64::from(len) {399 bail!(ArrayBoundsError(n, len));401 bail!(ArrayBoundsError(n, len));400 }402 }401 #[expect(403 #[expect(402 clippy::cast_possible_truncation,404 clippy::cast_possible_truncation,403 clippy::cast_sign_loss,405 clippy::cast_sign_loss,404 reason = "n is checked positive"406 reason = "n is checked range"405 )]407 )]406 let i = n as u32;408 let i = n as u32;407 arr.get(i)409 arr.get32(i)408 .with_description_src(loc, || format!("element <{i}> access"))?410 .with_description_src(loc, || format!("element <{i}> access"))?409 .ok_or_else(|| ArrayBoundsError(n, len))?411 .ok_or_else(|| ArrayBoundsError(n, len))?410 }412 }507 return Ok(());509 return Ok(());508 };510 };509511510 let thunk = build_b_thunk_uno(&value_ctx, value.clone());512 let env = Context::enter_using(&value_ctx, &value.0);513 let value = value.clone();511 builder514 builder512 .field(name)515 .field(name)513 .with_add(*plus)516 .with_add(*plus)514 .with_visibility(*visibility)517 .with_visibility(*visibility)515 .try_thunk(thunk)?;518 .try_thunk(Thunk!(move || evaluate(env, &value.1)))?;516 Ok(())519 Ok(())517}520}518521crates/jrsonnet-evaluator/src/function/mod.rsdiffbeforeafterboth11 prepared::{PreparedCall, parse_prepared_builtin_call},11 prepared::{PreparedCall, parse_prepared_builtin_call},12};12};13use crate::{13use crate::{14 PackedContextSupThis, Result, Thunk, Val,14 Context, PackedContextSupThis, Result, Thunk, Val,15 analyze::LFunction,15 analyze::LFunction,16 arr::arridx,16 evaluate::{17 evaluate::{destructure::destruct, ensure_sufficient_stack, evaluate, evaluate_trivial},17 destructure::{build_b_thunk, destruct},18 ensure_sufficient_stack, evaluate, evaluate_trivial,19 },20 function::builtin::BuiltinFunc,18 function::builtin::BuiltinFunc,21};19};83 &self.func.params[param_idx].destruct,81 &self.func.params[param_idx].destruct,84 fill,82 fill,85 thunk.clone(),83 thunk.clone(),86 &ctx,84 ctx,87 );85 );88 }86 }89 for &(param_idx, arg_idx) in prepared.named() {87 for &(param_idx, arg_idx) in prepared.named() {90 destruct(88 destruct(91 &self.func.params[param_idx].destruct,89 &self.func.params[param_idx].destruct,92 fill,90 fill,93 named[arg_idx].clone(),91 named[arg_idx].clone(),94 &ctx,92 ctx,95 );93 );96 }94 }979598 for ¶m_idx in prepared.defaults() {96 for ¶m_idx in prepared.defaults() {99 let param = &self.func.params[param_idx];97 let param = &self.func.params[param_idx];100 let (shape, expr) = param.default.as_ref().expect("default exists");98 let (shape, expr) = param.default.as_ref().expect("default exists");101 let thunk = build_b_thunk(&ctx, shape, expr.clone());99 let expr = expr.clone();100 let env = Context::enter_using(ctx, shape);101102 destruct(¶m.destruct, fill, thunk, &ctx);102 destruct(103 ¶m.destruct,104 fill,105 Thunk!(move || evaluate(env, &expr)),106 ctx,107 );103 }108 }104 });109 });152 }157 }153 }158 }154 /// Amount of non-default required arguments159 /// Amount of non-default required arguments155 pub fn params_len(&self) -> u32 {160 pub fn params_len32(&self) -> u32 {156 self.params().iter().filter(|p| !p.has_default()).count() as u32161 arridx(self.params().iter().filter(|p| !p.has_default()).count())157 }162 }158 /// Function name, as defined in code.163 /// Function name, as defined in code.159 pub fn name(&self) -> IStr {164 pub fn name(&self) -> IStr {crates/jrsonnet-evaluator/src/integrations/serde.rsdiffbeforeafterboth182 #[cfg(feature = "exp-bigint")]182 #[cfg(feature = "exp-bigint")]183 Self::BigInt(b) => b.serialize(serializer),183 Self::BigInt(b) => b.serialize(serializer),184 Self::Arr(arr) => {184 Self::Arr(arr) => {185 let mut seq = serializer.serialize_seq(Some(arr.len() as usize))?;185 let mut seq = serializer.serialize_seq(Some(arr.len()))?;186 for (i, element) in arr.iter().enumerate() {186 for (i, element) in arr.iter().enumerate() {187 let mut serde_error = None;187 let mut serde_error = None;188 in_description_frame(188 in_description_frame(203 seq.end()203 seq.end()204 }204 }205 Self::Obj(obj) => {205 Self::Obj(obj) => {206 let mut map = serializer.serialize_map(Some(obj.len() as usize))?;206 let mut map = serializer.serialize_map(Some(obj.len32() as usize))?;207 for (field, value) in obj.iter(207 for (field, value) in obj.iter(208 #[cfg(feature = "exp-preserve-order")]208 #[cfg(feature = "exp-preserve-order")]209 true,209 true,crates/jrsonnet-evaluator/src/obj/mod.rsdiffbeforeafterboth232324use crate::{24use crate::{25 CcUnbound, MaybeUnbound, Result, Thunk, Unbound, Val,25 CcUnbound, MaybeUnbound, Result, Thunk, Unbound, Val,26 arr::{PickObjectKeyValues, PickObjectValues},26 arr::{PickObjectKeyValues, PickObjectValues, arridx},27 bail,27 bail,28 error::{ErrorKind::*, suggest_object_fields},28 error::{ErrorKind::*, suggest_object_fields},29 evaluate::operator::evaluate_add_op,29 evaluate::operator::evaluate_add_op,510 // }510 // }511 /// Returns amount of visible object fields511 /// Returns amount of visible object fields512 /// If object only contains hidden fields - may return zero.512 /// If object only contains hidden fields - may return zero.513 pub fn len(&self) -> u32 {513 pub fn len(&self) -> usize {514 self.fields_visibility()514 self.fields_visibility()515 .values()515 .values()516 .filter(|d| d.visible())516 .filter(|d| d.visible())517 .count() as u32517 .count()518 }518 }519 pub fn len32(&self) -> u32 {520 arridx(self.len())521 }519 /// For each field, calls callback.522 /// For each field, calls callback.520 /// If callback returns false - ends iteration prematurely.523 /// If callback returns false - ends iteration prematurely.521 ///524 ///625 Entry::Vacant(v) => {628 Entry::Vacant(v) => {626 v.insert(CacheValue::Pending);629 v.insert(CacheValue::Pending);627 }630 }628 };631 }629 }632 }630 let result = self.get_idx_uncached(key, core);633 let result = self.get_idx_uncached(key, core);631 {634 {crates/jrsonnet-evaluator/src/stack.rsdiffbeforeafterboth11struct NightlyLocalKey<T>(pub T);11struct NightlyLocalKey<T>(pub T);12#[cfg(nightly)]12#[cfg(nightly)]13impl<T> NightlyLocalKey<T> {13impl<T> NightlyLocalKey<T> {14 #[inline(always)]14 #[inline]15 fn with<U>(&self, v: impl FnOnce(&T) -> U) -> U {15 fn with<U>(&self, v: impl FnOnce(&T) -> U) -> U {16 v(&self.0)16 v(&self.0)17 }17 }crates/jrsonnet-evaluator/src/trace/mod.rsdiffbeforeafterboth258}258}259#[cfg(feature = "explaining-traces")]259#[cfg(feature = "explaining-traces")]260impl TraceFormat for HiDocFormat {260impl TraceFormat for HiDocFormat {261 #[allow(clippy::too_many_lines)]261 fn write_trace(&self, out: &mut dyn fmt::Write, error: &Error) -> Result<(), fmt::Error> {262 fn write_trace(&self, out: &mut dyn fmt::Write, error: &Error) -> Result<(), fmt::Error> {262 struct ResetData {263 struct ResetData {263 loc: Span,264 loc: Span,crates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth637 }637 }638 <Self as Typed>::TYPE.check(&value)?;638 <Self as Typed>::TYPE.check(&value)?;639 // Any::downcast_ref::<ByteArray>(&a);639 // Any::downcast_ref::<ByteArray>(&a);640 let mut out = Vec::with_capacity(a.len() as usize);640 let mut out = Vec::with_capacity(a.len());641 for e in a.iter() {641 for e in a.iter() {642 let r = e?;642 let r = e?;643 out.push(u8::from_untyped(r)?);643 out.push(u8::from_untyped(r)?);crates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth277 /// For strings, will create a copy of specified interval.277 /// For strings, will create a copy of specified interval.278 ///278 ///279 /// For arrays, nothing will be copied on this call, instead [`ArrValue::Slice`] view will be returned.279 /// For arrays, nothing will be copied on this call, instead [`ArrValue::Slice`] view will be returned.280 pub fn slice(280 pub fn slice32(281 self,281 self,282 index: Option<i32>,282 index: Option<i32>,283 end: Option<i32>,283 end: Option<i32>,321 .into(),321 .into(),322 ))322 ))323 }323 }324 Self::Arr(arr) => Ok(Self::Arr(arr.clone().slice(324 Self::Arr(arr) => Ok(Self::Arr(arr.clone().slice32(325 index,325 index,326 end,326 end,327 #[expect(327 #[expect(658 if ArrValue::ptr_eq(a, b) {658 if ArrValue::ptr_eq(a, b) {659 return Ok(true);659 return Ok(true);660 }660 }661 if a.len() != b.len() {661 if a.len32() != b.len32() {662 return Ok(false);662 return Ok(false);663 }663 }664 for (a, b) in a.iter().zip(b.iter()) {664 for (a, b) in a.iter().zip(b.iter()) {crates/jrsonnet-formatter/src/lib.rsdiffbeforeafterboth477 &mut out,477 &mut out,478 );478 );479479480 let mut compspecs = compspecs.into_iter().peekable();481 while let Some(mem) = compspecs.next() {480 for mem in compspecs {482 if mem.should_start_with_newline {481 if mem.should_start_with_newline {483 p!(out, nl);482 p!(out, nl);484 }483 }crates/jrsonnet-peg-parser/src/lib.rsdiffbeforeafterboth273 Expr::ArrComp(Box::new(expr), specs)273 Expr::ArrComp(Box::new(expr), specs)274 }274 }275 pub rule number_expr(s: &ParserSettings) -> Expr275 pub rule number_expr(s: &ParserSettings) -> Expr276 = n:number() {? if let Some(n) = NumValue::new(n) {276 = n:number() {? NumValue::new(n).map_or_else(|| Err("!!!numbers are finite"), |n| Ok(Expr::Num(n)))}277 Ok(Expr::Num(n))278 } else {279 Err("!!!numbers are finite")280 }}281277282 rule spanned<T: Acyclic>(x: rule<T>, s: &ParserSettings) -> Spanned<T>278 rule spanned<T: Acyclic>(x: rule<T>, s: &ParserSettings) -> Spanned<T>283 = a:position!() n:x() b:position!() { Spanned::new(n, Span(s.source.clone(), a as u32, b as u32)) }279 = a:position!() n:x() b:position!() { Spanned::new(n, Span(s.source.clone(), codeidx(a), codeidx(b))) }284280285 pub rule var_expr(s: &ParserSettings) -> Expr281 pub rule var_expr(s: &ParserSettings) -> Expr286 = n:spanned(<id()>, s) { Expr::Var(n) }282 = n:spanned(<id()>, s) { Expr::Var(n) }287 pub rule id_loc(s: &ParserSettings) -> Spanned<Expr>283 pub rule id_loc(s: &ParserSettings) -> Spanned<Expr>288 = a:position!() n:id() b:position!() { Spanned::new(Expr::Str(n), Span(s.source.clone(), a as u32,b as u32)) }284 = a:position!() n:id() b:position!() { Spanned::new(Expr::Str(n), Span(s.source.clone(), codeidx(a), codeidx(b))) }289 pub rule if_then_else_expr(s: &ParserSettings) -> Expr285 pub rule if_then_else_expr(s: &ParserSettings) -> Expr290 = cond:ifspec(s) _ keyword("then") _ cond_then:expr(s) cond_else:(_ keyword("else") _ e:expr(s) {e})? {Expr::IfElse(Box::new(IfElse{286 = cond:ifspec(s) _ keyword("then") _ cond_then:expr(s) cond_else:(_ keyword("else") _ e:expr(s) {e})? {Expr::IfElse(Box::new(IfElse{291 cond,287 cond,421 }417 }422}418}419420fn codeidx(i: usize) -> u32 {421 u32::try_from(i).expect("code has 4g hard limit")422}423423424pub type ParseError = peg::error::ParseError<peg::str::LineCol>;424pub type ParseError = peg::error::ParseError<peg::str::LineCol>;425pub fn parse(str: &str, settings: &ParserSettings) -> Result<Expr, ParseError> {425pub fn parse(str: &str, settings: &ParserSettings) -> Result<Expr, ParseError> {428/// Used for importstr values428/// Used for importstr values429pub fn string_to_expr(str: IStr, settings: &ParserSettings) -> Spanned<Expr> {429pub fn string_to_expr(str: IStr, settings: &ParserSettings) -> Spanned<Expr> {430 let len = str.len();430 let len = str.len();431 Spanned::new(Expr::Str(str), Span(settings.source.clone(), 0, len as u32))431 Spanned::new(432 Expr::Str(str),433 Span(settings.source.clone(), 0, codeidx(len)),434 )432}435}433436crates/jrsonnet-pkg/src/install/accessor.rsdiffbeforeafterboth66 Ok(Some(out))66 Ok(Some(out))67 }67 }68 #[allow(clippy::significant_drop_tightening, reason = "false-positive")]68 #[allow(clippy::significant_drop_tightening, reason = "false-positive")]69 #[allow(70 clippy::iter_not_returning_iterator,71 reason = "idk for a better name, it is still inner iteration"72 )]69 pub fn iter<E>(73 pub fn iter<E>(70 &self,74 &self,71 subdir: &SubDir,75 subdir: &SubDir,crates/jrsonnet-rowan-parser/src/parser.rsdiffbeforeafterboth226 self.nth_at(0, kind)226 self.nth_at(0, kind)227 }227 }228 pub fn nth_at(&self, n: usize, kind: SyntaxKind) -> bool {228 pub fn nth_at(&self, n: usize, kind: SyntaxKind) -> bool {229 if n == 0 {229 if n == 0230 if let ExpectedSyntax::Unnamed(kinds) = self.expected_syntax_tracking_state.get() {230 && let ExpectedSyntax::Unnamed(kinds) = self.expected_syntax_tracking_state.get()231 {231 let kinds = kinds.with(kind);232 let kinds = kinds.with(kind);232 self.expected_syntax_tracking_state233 self.expected_syntax_tracking_state233 .set(ExpectedSyntax::Unnamed(kinds));234 .set(ExpectedSyntax::Unnamed(kinds));234 }235 }235 }236 self.nth(n) == kind236 self.nth(n) == kind237 }237 }238 pub fn at_ts(&self, set: SyntaxKindSet) -> bool {238 pub fn at_ts(&self, set: SyntaxKindSet) -> bool {crates/jrsonnet-stdlib/src/arrays.rsdiffbeforeafterboth52 step: Option<Option<BoundedUsize<1, { i32::MAX as usize }>>>,52 step: Option<Option<BoundedUsize<1, { i32::MAX as usize }>>>,53) -> Result<Val> {53) -> Result<Val> {54 indexable54 indexable55 .slice(index.flatten(), end.flatten(), step.flatten())55 .slice32(index.flatten(), end.flatten(), step.flatten())56 .map(Val::from)56 .map(Val::from)57}57}5858204 let item = item?.clone();204 let item = item?.clone();205 if let Val::Arr(items) = item {205 if let Val::Arr(items) = item {206 if !first {206 if !first {207 out.reserve(joiner_items.len() as usize);207 out.reserve(joiner_items.len());208 // TODO: extend208 // TODO: extend209 for item in joiner_items.iter() {209 for item in joiner_items.iter() {210 out.push(item?);210 out.push(item?);211 }211 }212 }212 }213 first = false;213 first = false;214 out.reserve(items.len() as usize);214 out.reserve(items.len());215 for item in items.iter() {215 for item in items.iter() {216 out.push(item?);216 out.push(item?);217 }217 }372372373#[builtin]373#[builtin]374pub fn builtin_remove_at(arr: ArrValue, at: i32) -> Result<ArrValue> {374pub fn builtin_remove_at(arr: ArrValue, at: i32) -> Result<ArrValue> {375 let newArrLeft = arr.clone().slice(None, Some(at), None);375 let newArrLeft = arr.clone().slice32(None, Some(at), None);376 let newArrRight = arr.slice(Some(at + 1), None, None);376 let newArrRight = arr.slice32(Some(at + 1), None, None);377377378 Ok(ArrValue::extended(newArrLeft, newArrRight).ok_or_else(|| error!("array is too large"))?)378 ArrValue::extended(newArrLeft, newArrRight).ok_or_else(|| error!("array is too large"))379}379}380380381#[builtin]381#[builtin]crates/jrsonnet-stdlib/src/manifest/xml.rsdiffbeforeafterboth44 bail!("JSONML value should have tag (array length should be >=1)");44 bail!("JSONML value should have tag (array length should be >=1)");45 }45 }46 let tag = String::from_untyped(46 let tag = String::from_untyped(47 arr.get(0)47 arr.get32(0)48 .description("getting JSONML tag")?48 .description("getting JSONML tag")?49 .expect("length checked"),49 .expect("length checked"),50 )50 )51 .description("parsing JSONML tag")?;51 .description("parsing JSONML tag")?;525253 let (has_attrs, attrs) = if arr.len() >= 2 {53 let (has_attrs, attrs) = if arr.len32() >= 2 {54 let maybe_attrs = arr54 let maybe_attrs = arr55 .get(1)55 .get32(1)56 .with_description(|| "getting JSONML attrs")?56 .with_description(|| "getting JSONML attrs")?57 .expect("length checked");57 .expect("length checked");58 if let Val::Obj(attrs) = maybe_attrs {58 if let Val::Obj(attrs) = maybe_attrs {68 attrs,68 attrs,69 children: in_description_frame(69 children: in_description_frame(70 || "parsing children".to_owned(),70 || "parsing children".to_owned(),71 || {71 || FromUntyped::from_untyped(Val::Arr(arr.slice(if has_attrs { 2 } else { 1 }..))),72 FromUntyped::from_untyped(Val::Arr(arr.slice(73 Some(if has_attrs { 2 } else { 1 }),74 None,75 None,76 )))77 },78 )?,72 )?,79 })73 })80 }74 }crates/jrsonnet-stdlib/src/misc.rsdiffbeforeafterboth16pub fn builtin_length(x: Either![IStr, ArrValue, ObjValue, FuncVal]) -> u32 {16pub fn builtin_length(x: Either![IStr, ArrValue, ObjValue, FuncVal]) -> u32 {17 use Either4::*;17 use Either4::*;18 match x {18 match x {19 A(x) => x.chars().count() as u32,19 A(x) => u32::try_from(x.chars().count()).expect("4g limit"),20 B(x) => x.len(),20 B(x) => x.len32(),21 C(x) => x.len(),21 C(x) => x.len32(),22 D(f) => f.params_len(),22 D(f) => f.params_len32(),23 }23 }24}24}2525102 } else if b.len() == a.len() {102 } else if b.len() == a.len() {103 return equals(&Val::Arr(a), &Val::Arr(b));103 return equals(&Val::Arr(a), &Val::Arr(b));104 }104 }105 for (a, b) in a.iter().take(b.len() as usize).zip(b.iter()) {105 for (a, b) in a.iter().take(b.len()).zip(b.iter()) {106 let a = a?;106 let a = a?;107 let b = b?;107 let b = b?;108 if !equals(&a, &b)? {108 if !equals(&a, &b)? {127 return equals(&Val::Arr(a), &Val::Arr(b));127 return equals(&Val::Arr(a), &Val::Arr(b));128 }128 }129 let a_len = a.len();129 let a_len = a.len();130 for (a, b) in a.iter().skip((a_len - b.len()) as usize).zip(b.iter()) {130 for (a, b) in a.iter().skip(a_len - b.len()).zip(b.iter()) {131 let a = a?;131 let a = a?;132 let b = b?;132 let b = b?;133 if !equals(&a, &b)? {133 if !equals(&a, &b)? {crates/jrsonnet-stdlib/src/sets.rsdiffbeforeafterboth8#[allow(non_snake_case)]8#[allow(non_snake_case)]9pub fn builtin_set_member(x: Thunk<Val>, arr: ArrValue, #[default] keyF: KeyF) -> Result<bool> {9pub fn builtin_set_member(x: Thunk<Val>, arr: ArrValue, #[default] keyF: KeyF) -> Result<bool> {10 let mut low = 0;10 let mut low = 0;11 let mut high = arr.len();11 let mut high = arr.len32();121213 let x = keyF.eval(x)?;13 let x = keyF.eval(x)?;141415 while low < high {15 while low < high {16 let middle = u32::midpoint(high, low);16 let middle = u32::midpoint(high, low);17 let comp = keyF.eval(arr.get_lazy(middle).expect("in bounds"))?;17 let comp = keyF.eval(arr.get_lazy32(middle).expect("in bounds"))?;18 match Val::try_cmp(&comp, &x)? {18 match Val::try_cmp(&comp, &x)? {19 Ordering::Less => low = middle + 1,19 Ordering::Less => low = middle + 1,20 Ordering::Equal => return Ok(true),20 Ordering::Equal => return Ok(true),crates/jrsonnet-stdlib/src/sort.rsdiffbeforeafterboth696970fn sort_keyf(values: ArrValue, keyf: KeyF) -> Result<Vec<Thunk<Val>>> {70fn sort_keyf(values: ArrValue, keyf: KeyF) -> Result<Vec<Thunk<Val>>> {71 // Slow path, user provided key getter71 // Slow path, user provided key getter72 let mut vk = Vec::with_capacity(values.len() as usize);72 let mut vk = Vec::with_capacity(values.len());73 for value in values.iter_lazy() {73 for value in values.iter_lazy() {74 vk.push((value.clone(), keyf.eval(value)?));74 vk.push((value.clone(), keyf.eval(value)?));75 }75 }137137138fn uniq_keyf(arr: ArrValue, keyf: KeyF) -> Result<Vec<Thunk<Val>>> {138fn uniq_keyf(arr: ArrValue, keyf: KeyF) -> Result<Vec<Thunk<Val>>> {139 let mut out = Vec::new();139 let mut out = Vec::new();140 let last_value = arr.get_lazy(0).unwrap();140 let last_value = arr.get_lazy32(0).unwrap();141 let mut last_key = keyf.eval(last_value.clone())?;141 let mut last_key = keyf.eval(last_value.clone())?;142 out.push(last_value);142 out.push(last_value);143143crates/jrsonnet-types/src/lib.rsdiffbeforeafterboth103 Self::BoundedNumber(a, b) => write!(103 Self::BoundedNumber(a, b) => write!(104 f,104 f,105 "BoundedNumber<{}, {}>",105 "BoundedNumber<{}, {}>",106 a.map(|e| e.to_string())106 a.map_or_else(|| "open".to_owned(), |e| e.to_string()),107 .unwrap_or_else(|| "open".to_owned()),107 b.map_or_else(|| "open".to_owned(), |e| e.to_string())108 b.map(|e| e.to_string())109 .unwrap_or_else(|| "open".to_owned())110 )?,108 )?,111 Self::ArrayRef(a) => print_array(a, f)?,109 Self::ArrayRef(a) => print_array(a, f)?,112 Self::Array(a) => print_array(a, f)?,110 Self::Array(a) => print_array(a, f)?,tests/tests/cpp_test_suite.rsdiffbeforeafterboth60 let _entered = s.enter();60 let _entered = s.enter();616162 let trace_format = CompactFormat {62 let trace_format = CompactFormat {63 resolver: resolver.clone(),63 resolver,64 max_trace: 20,64 max_trace: 20,65 padding: 4,65 padding: 4,66 };66 };xtask/src/bench.rsdiffbeforeafterboth919192 let start = Instant::now();92 let start = Instant::now();93 let child = cmd.spawn()?;93 let child = cmd.spawn()?;94 #[allow(95 clippy::cast_possible_wrap,96 reason = "it is signed, but libc didn't set unsigned for it"97 )]94 let pid = child.id() as libc::pid_t;98 let pid = child.id() as libc::pid_t;95 // We'll reap via wait4 ourselves; don't let std touch this handle again.99 // We'll reap via wait4 ourselves; don't let std touch this handle again.96 mem::forget(child);100 mem::forget(child);133 );137 );134 eprintln!(138 eprintln!(135 " max_rss: {} ± {} KiB [{}..{}]",139 " max_rss: {} ± {} KiB [{}..{}]",136 r.max_rss_kib.mean as i64,140 r.max_rss_kib.mean.trunc(),137 r.max_rss_kib.stddev as i64,141 r.max_rss_kib.stddev.trunc(),138 r.max_rss_kib.min as i64,142 r.max_rss_kib.min.trunc(),139 r.max_rss_kib.max as i64,143 r.max_rss_kib.max.trunc(),140 );144 );141 Ok(())145 Ok(())142}146}xtask/src/sourcegen/mod.rsdiffbeforeafterboth113 Ok(())113 Ok(())114}114}115115116#[allow(clippy::too_many_lines)]116fn generate_syntax_kinds(kinds: &KindsSrc, grammar: &AstSrc, lexer: bool) -> Result<String> {117fn generate_syntax_kinds(kinds: &KindsSrc, grammar: &AstSrc, lexer: bool) -> Result<String> {117 let t_macros = kinds.tokens().filter_map(TokenKind::expand_t_macros);118 let t_macros = kinds.tokens().filter_map(TokenKind::expand_t_macros);118 let token_kinds = kinds.tokens().map(|t| t.expand_kind(lexer));119 let token_kinds = kinds.tokens().map(|t| t.expand_kind(lexer));