git.delta.rocks / jrsonnet / refs/commits / 1bfba233fc03

difftreelog

refactor reenable clippy integer cast checks

slqpxoouYaroslav Bolyukin2026-04-25parent: #191649c.patch.diff
in: master

17 files changed

modifiedCargo.tomldiffbeforeafterboth
122wildcard_imports = "allow"122wildcard_imports = "allow"
123enum_glob_use = "allow"123enum_glob_use = "allow"
124module_name_repetitions = "allow"124module_name_repetitions = "allow"
125# TODO: fix individual issues, however this works as intended almost everywhere
126cast_precision_loss = "allow"
127cast_possible_wrap = "allow"
128cast_possible_truncation = "allow"
129cast_sign_loss = "allow"
130# False positives125# False positives
131# https://github.com/rust-lang/rust-clippy/issues/6902126# https://github.com/rust-lang/rust-clippy/issues/6902
132use_self = "allow"127use_self = "allow"
modifiedcrates/jrsonnet-evaluator/src/arr/mod.rsdiffbeforeafterboth
128 #[must_use]128 #[must_use]
129 pub fn slice(self, index: Option<i32>, end: Option<i32>, step: Option<NonZeroU32>) -> Self {129 pub fn slice(self, index: Option<i32>, end: Option<i32>, step: Option<NonZeroU32>) -> Self {
130 let get_idx = |pos: Option<i32>, len: usize, default| match pos {130 let get_idx = |pos: Option<i32>, len: usize, default| match pos {
131 #[expect(
132 clippy::cast_sign_loss,
133 reason = "abs value is used, len is limited to u31"
134 )]
131 Some(v) if v < 0 => len.saturating_sub((-v) as usize),135 Some(v) if v < 0 => len.saturating_sub((-v) as usize),
136 #[expect(clippy::cast_sign_loss, reason = "abs value is used")]
132 Some(v) => (v as usize).min(len),137 Some(v) => (v as usize).min(len),
133 None => default,138 None => default,
134 };139 };
142147
143 Self::new(SliceArray {148 Self::new(SliceArray {
144 inner: self,149 inner: self,
150 #[expect(clippy::cast_possible_truncation, reason = "len is limited to u31")]
145 from: index as u32,151 from: index as u32,
152 #[expect(clippy::cast_possible_truncation, reason = "len is limited to u31")]
146 to: end as u32,153 to: end as u32,
147 step: step.get(),154 step: step.get(),
148 })155 })
modifiedcrates/jrsonnet-evaluator/src/arr/spec.rsdiffbeforeafterboth
350 pub fn new_inclusive(start: i32, end: i32) -> Self {350 pub fn new_inclusive(start: i32, end: i32) -> Self {
351 Self { start, end }351 Self { start, end }
352 }352 }
353 #[expect(
354 clippy::cast_sign_loss,
355 reason = "the math is valid with wrapping, sign loss works as intended"
356 )]
357 fn size(&self) -> usize {
358 (self.end as usize)
359 .wrapping_sub(self.start as usize)
360 .wrapping_add(1)
361 }
353 fn range(&self) -> impl ExactSizeIterator<Item = i32> + DoubleEndedIterator {362 fn range(&self) -> impl ExactSizeIterator<Item = i32> + DoubleEndedIterator {
354 WithExactSize(363 WithExactSize(self.start..=self.end, self.size())
355 self.start..=self.end,
356 (self.end as usize)
357 .wrapping_sub(self.start as usize)
358 .wrapping_add(1),
359 )
360 }364 }
361}365}
362366
363impl ArrayLike for RangeArray {367impl ArrayLike for RangeArray {
364 fn len(&self) -> usize {368 fn len(&self) -> usize {
365 self.range().len()369 self.size()
366 }370 }
367 fn is_empty(&self) -> bool {371 fn is_empty(&self) -> bool {
368 self.range().len() == 0372 self.size() == 0
369 }373 }
370374
371 fn get(&self, index: usize) -> Result<Option<Val>> {375 fn get(&self, index: usize) -> Result<Option<Val>> {
431 fn evaluate(&self, index: usize, value: Val) -> Result<Val> {435 fn evaluate(&self, index: usize, value: Val) -> Result<Val> {
432 match &self.mapper {436 match &self.mapper {
433 ArrayMapper::Plain(f) => f.call(value),437 ArrayMapper::Plain(f) => f.call(value),
438 #[expect(
439 clippy::cast_possible_truncation,
440 reason = "array len is limited to u31"
441 )]
434 ArrayMapper::WithIndex(f) => f.call(index as u32, value),442 ArrayMapper::WithIndex(f) => f.call(index as u32, value),
435 }443 }
436 }444 }
modifiedcrates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth
548 bail!(FractionalIndex)548 bail!(FractionalIndex)
549 }549 }
550 if n < 0.0 {550 if n < 0.0 {
551 #[expect(
552 clippy::cast_possible_truncation,
553 reason = "it would be truncated anyway"
554 )]
555 let n = n as isize;
551 bail!(ArrayBoundsError(n as isize, v.len()));556 bail!(ArrayBoundsError(n, v.len()));
552 }557 }
558 #[expect(
559 clippy::cast_possible_truncation,
560 clippy::cast_sign_loss,
561 reason = "n is checked postive"
562 )]
553 v.get(n as usize)?563 v.get(n as usize)?
554 .ok_or_else(|| ArrayBoundsError(n as isize, v.len()))?564 .ok_or_else(|| ArrayBoundsError(n as isize, v.len()))?
555 }565 }
568 bail!(FractionalIndex)578 bail!(FractionalIndex)
569 }579 }
570 if n < 0.0 {580 if n < 0.0 {
581 #[expect(
582 clippy::cast_possible_truncation,
583 reason = "it would be truncated anyway"
584 )]
585 let n = n as isize;
571 bail!(ArrayBoundsError(n as isize, s.into_flat().chars().count()));586 bail!(ArrayBoundsError(n, s.into_flat().chars().count()));
572 }587 }
588 #[expect(
589 clippy::cast_sign_loss,
590 clippy::cast_possible_truncation,
591 reason = "n is positive, overflow will truncate as expected"
592 )]
593 let n = n as usize;
573 let v: IStr = s594 let v: IStr = s
574 .clone()595 .clone()
575 .into_flat()596 .into_flat()
576 .chars()597 .chars()
577 .skip(n as usize)598 .skip(n)
578 .take(1)599 .take(1)
579 .collect::<String>()600 .collect::<String>()
580 .into();601 .into();
581 if v.is_empty() {602 if v.is_empty() {
582 bail!(StringBoundsError(n as usize, s.into_flat().chars().count()))603 bail!(StringBoundsError(n, s.into_flat().chars().count()))
583 }604 }
584 StrValue::Flat(v)605 StrValue::Flat(v)
585 }),606 }),
modifiedcrates/jrsonnet-evaluator/src/evaluate/operator.rsdiffbeforeafterboth
20 (Plus, Num(n)) => Val::Num(*n),20 (Plus, Num(n)) => Val::Num(*n),
21 (Minus, Num(n)) => Val::try_num(-n.get())?,21 (Minus, Num(n)) => Val::try_num(-n.get())?,
22 (Not, Bool(v)) => Bool(!v),22 (Not, Bool(v)) => Bool(!v),
23 #[expect(clippy::cast_precision_loss, reason = "as spec")]
23 (BitNot, Num(n)) => Val::try_num(!(n.get() as i64) as f64)?,24 (BitNot, Num(n)) => Val::try_num(!n.truncate_for_bitwise()? as f64)?,
24 (op, o) => bail!(UnaryOperatorDoesNotOperateOnType(op, o.value_type())),25 (op, o) => bail!(UnaryOperatorDoesNotOperateOnType(op, o.value_type())),
25 })26 })
26}27}
73pub fn evaluate_mul_op(a: &Val, b: &Val) -> Result<Val> {74pub fn evaluate_mul_op(a: &Val, b: &Val) -> Result<Val> {
74 use Val::*;75 use Val::*;
75 Ok(match (a, b) {76 Ok(match (a, b) {
77 #[expect(
78 clippy::cast_possible_truncation,
79 clippy::cast_sign_loss,
80 reason = "should not be used with values too large, negative == 0"
81 )]
76 (Str(s), Num(c)) => Val::string(s.to_string().repeat(c.get() as usize)),82 (Str(s), Num(c)) => Val::string(s.to_string().repeat(c.get() as usize)),
83 #[expect(
84 clippy::cast_possible_truncation,
85 clippy::cast_sign_loss,
86 reason = "should not be used with values too large"
87 )]
77 (Num(c), Str(s)) => Val::string(s.to_string().repeat(c.get() as usize)),88 (Num(c), Str(s)) => Val::string(s.to_string().repeat(c.get() as usize)),
7889
79 (Num(v1), Num(v2)) => Val::try_num(v1.get() * v2.get())?,90 (Num(v1), Num(v2)) => Val::try_num(v1.get() * v2.get())?,
220231
221 (Num(v1), BitAnd, Num(v2)) => {232 (Num(v1), BitAnd, Num(v2)) =>
233 {
234 #[expect(
235 clippy::cast_precision_loss,
236 reason = "values are within safe integer ranges"
237 )]
222 Val::try_num((v1.truncate_for_bitwise()? & v2.truncate_for_bitwise()?) as f64)?238 Val::try_num((v1.truncate_for_bitwise()? & v2.truncate_for_bitwise()?) as f64)?
223 }239 }
224 (Num(v1), BitOr, Num(v2)) => {240 (Num(v1), BitOr, Num(v2)) =>
241 {
242 #[expect(
243 clippy::cast_precision_loss,
244 reason = "values are within safe integer ranges"
245 )]
225 Val::try_num((v1.truncate_for_bitwise()? | v2.truncate_for_bitwise()?) as f64)?246 Val::try_num((v1.truncate_for_bitwise()? | v2.truncate_for_bitwise()?) as f64)?
226 }247 }
227 (Num(v1), BitXor, Num(v2)) => {248 (Num(v1), BitXor, Num(v2)) =>
249 {
250 #[expect(
251 clippy::cast_precision_loss,
252 reason = "values are within safe integer ranges"
253 )]
228 Val::try_num((v1.truncate_for_bitwise()? ^ v2.truncate_for_bitwise()?) as f64)?254 Val::try_num((v1.truncate_for_bitwise()? ^ v2.truncate_for_bitwise()?) as f64)?
229 }255 }
230 (Num(v1), Lhs, Num(v2)) => {256 (Num(v1), Lhs, Num(v2)) => {
234 let base = v1.truncate_for_bitwise()?;260 let base = v1.truncate_for_bitwise()?;
235 let exp = v2.truncate_for_bitwise()? % 64;261 let exp = v2.truncate_for_bitwise()? % 64;
236262
263 #[expect(clippy::cast_sign_loss, reason = "exp is positive")]
237 if exp >= 1 && base >= (1i64 << (63 - exp as u32)) {264 if exp >= 1 && base >= (1i64 << (63 - exp as u32)) {
238 bail!("left shift would overflow")265 bail!("left shift would overflow")
239 }266 }
267 #[expect(
268 clippy::cast_precision_loss,
269 clippy::cast_sign_loss,
270 reason = "checked as original impl"
271 )]
240 Val::try_num(base.wrapping_shl(exp as u32) as f64)?272 Val::try_num(base.wrapping_shl(exp as u32) as f64)?
241 }273 }
242 (Num(v1), Rhs, Num(v2)) => {274 (Num(v1), Rhs, Num(v2)) => {
243 if v2.get() < 0.0 {275 if v2.get() < 0.0 {
244 bail!("shift by negative exponent")276 bail!("shift by negative exponent")
245 }277 }
278 #[expect(
279 clippy::cast_sign_loss,
280 clippy::cast_possible_truncation,
281 reason = "checked as original impl"
282 )]
246 let exp = ((v2.get() as i64) & 63) as u32;283 let exp = ((v2.get() as i64) & 63) as u32;
284 #[expect(clippy::cast_precision_loss, reason = "checked as upstream impl")]
247 Val::try_num(v1.truncate_for_bitwise()?.wrapping_shr(exp) as f64)?285 Val::try_num(v1.truncate_for_bitwise()?.wrapping_shr(exp) as f64)?
248 }286 }
249287
modifiedcrates/jrsonnet-evaluator/src/integrations/serde.rsdiffbeforeafterboth
69 where69 where
70 E: de::Error,70 E: de::Error,
71 {71 {
72 #[expect(
73 clippy::cast_precision_loss,
74 reason = "this is how it works with stdlib functions"
75 )]
72 Ok(Val::Num(NumValue::new(v as f64).expect("no overflow")))76 Ok(Val::Num(NumValue::new(v as f64).expect("no overflow")))
73 }77 }
74 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>78 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
75 where79 where
76 E: de::Error,80 E: de::Error,
77 {81 {
82 #[expect(
83 clippy::cast_precision_loss,
84 reason = "this is how it works with stdlib functions"
85 )]
78 Ok(Val::Num(NumValue::new(v as f64).expect("no overflow")))86 Ok(Val::Num(NumValue::new(v as f64).expect("no overflow")))
79 }87 }
8088
161 Self::Num(n) => {169 Self::Num(n) => {
162 let n = n.get();170 let n = n.get();
163 if n.fract() == 0.0 {171 if n.fract() == 0.0 {
172 #[expect(
173 clippy::cast_possible_truncation,
174 reason = "no correct implementation is possible here; expected"
175 )]
164 let n = n as i64;176 let n = n as i64;
165 serializer.serialize_i64(n)177 serializer.serialize_i64(n)
166 } else {178 } else {
modifiedcrates/jrsonnet-evaluator/src/obj/mod.rsdiffbeforeafterboth
793 })793 })
794 }794 }
795
796 #[allow(dead_code, reason = "used in object ...rest destructuring")]
795 pub(crate) fn as_standalone(&self) -> StandaloneSuperCore {797 pub(crate) fn as_standalone(&self) -> StandaloneSuperCore {
796 StandaloneSuperCore {798 StandaloneSuperCore {
797 sup: CoreIdx {799 sup: CoreIdx {
modifiedcrates/jrsonnet-evaluator/src/stdlib/format.rsdiffbeforeafterboth
1//! faster std.format impl1//! faster std.format impl
2#![allow(clippy::too_many_arguments)]2#![allow(clippy::too_many_arguments)]
3#![expect(
4 clippy::cast_possible_truncation,
5 clippy::cast_sign_loss,
6 reason = "many safe integer casts, behavior on overflow is not specified"
7)]
38
4use jrsonnet_gcmodule::Trace;9use jrsonnet_gcmodule::Trace;
5use jrsonnet_interner::IStr;10use jrsonnet_interner::IStr;
modifiedcrates/jrsonnet-evaluator/src/trace/mod.rsdiffbeforeafterboth
129 } else {129 } else {
130 false130 false
131 };131 };
132 #[expect(clippy::cast_possible_truncation, reason = "code is limited by 4gb")]
132 let mut location = path133 let mut location = path
133 .map_source_locations(&[offset as u32])134 .map_source_locations(&[offset as u32])
134 .into_iter()135 .into_iter()
modifiedcrates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth
157 }157 }
158}158}
159159
160#[expect(clippy::cast_precision_loss, reason = "checked to not overflow")]
160pub const MAX_SAFE_INTEGER: f64 = ((1u64 << (f64::MANTISSA_DIGITS)) - 1) as f64;161pub const MAX_SAFE_INTEGER: f64 = ((1u64 << (f64::MANTISSA_DIGITS)) - 1) as f64;
162#[expect(clippy::cast_precision_loss, reason = "checked to not overflow")]
161pub const MIN_SAFE_INTEGER: f64 = (-((1i64 << (f64::MANTISSA_DIGITS)) - 1)) as f64;163pub const MIN_SAFE_INTEGER: f64 = (-((1i64 << (f64::MANTISSA_DIGITS)) - 1)) as f64;
162164
163macro_rules! impl_int {165macro_rules! impl_int {
179 stringify!($ty)181 stringify!($ty)
180 )182 )
181 }183 }
184 #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation, reason = "checked by TYPE")]
182 Ok(n as Self)185 Ok(n as Self)
183 }186 }
184 _ => unreachable!(),187 _ => unreachable!(),
198macro_rules! impl_bounded_int {201macro_rules! impl_bounded_int {
199 ($($name:ident = $ty:ty)*) => {$(202 ($($name:ident = $ty:ty)*) => {$(
200 #[derive(Clone, Copy)]203 #[derive(Clone, Copy)]
204 #[allow(clippy::cast_possible_truncation, reason = "overflow is api misuse")]
201 pub struct $name<const MIN: $ty, const MAX: $ty>($ty);205 pub struct $name<const MIN: $ty, const MAX: $ty>($ty);
202 impl<const MIN: $ty, const MAX: $ty> $name<MIN, MAX> {206 impl<const MIN: $ty, const MAX: $ty> $name<MIN, MAX> {
203 pub const fn new(value: $ty) -> Option<$name<MIN, MAX>> {207 pub const fn new(value: $ty) -> Option<$name<MIN, MAX>> {
219 }223 }
220224
221 impl<const MIN: $ty, const MAX: $ty> Typed for $name<MIN, MAX> {225 impl<const MIN: $ty, const MAX: $ty> Typed for $name<MIN, MAX> {
226 #[allow(clippy::cast_possible_truncation, clippy::cast_precision_loss, reason = "overflow is api misuse")]
222 const TYPE: &'static ComplexValType =227 const TYPE: &'static ComplexValType =
223 &ComplexValType::BoundedNumber(228 &ComplexValType::BoundedNumber(
224 Some(MIN as f64),229 Some(MIN as f64),
239 stringify!($ty)244 stringify!($ty)
240 )245 )
241 }246 }
247 #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss, reason = "overflow is api misuse, the range is checked by TYPE")]
242 Ok(Self(n as $ty))248 Ok(Self(n as $ty))
243 }249 }
244 _ => unreachable!(),250 _ => unreachable!(),
318 if n.trunc() != n {324 if n.trunc() != n {
319 bail!("cannot convert number with fractional part to usize")325 bail!("cannot convert number with fractional part to usize")
320 }326 }
327 #[allow(
328 clippy::cast_possible_truncation,
329 clippy::cast_sign_loss,
330 reason = "the range is checked by TYPE"
331 )]
321 Ok(n as Self)332 Ok(n as Self)
322 }333 }
323 _ => unreachable!(),334 _ => unreachable!(),
modifiedcrates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth
295 };295 };
296 let mut get_idx = |pos: Option<i32>, default| {296 let mut get_idx = |pos: Option<i32>, default| {
297 match pos {297 match pos {
298 #[expect(clippy::cast_sign_loss, reason = "abs value is used")]
298 Some(v) if v < 0 => get_len().saturating_sub((-v) as usize),299 Some(v) if v < 0 => get_len().saturating_sub((-v as isize) as usize),
299 // No need to clamp, as iterator interface is used300 // No need to clamp, as iterator interface is used
301 #[expect(clippy::cast_sign_loss, reason = "abs value is used")]
300 Some(v) => v as usize,302 Some(v) => v as usize,
301 None => default,303 None => default,
302 }304 }
322 Self::Arr(arr) => Ok(Self::Arr(arr.clone().slice(324 Self::Arr(arr) => Ok(Self::Arr(arr.clone().slice(
323 index,325 index,
324 end,326 end,
327 #[expect(
328 clippy::cast_possible_truncation,
329 reason = "overflow will result with skip too large which would be equivalent"
330 )]
325 step.map(|v| NonZeroU32::new(v.value() as u32).expect("bounded != 0")),331 step.map(|v| NonZeroU32::new(v.value() as u32).expect("bounded != 0")),
326 ))),332 ))),
327 }333 }
446 if self.0 < MIN_SAFE_INTEGER || self.0 > MAX_SAFE_INTEGER {452 if self.0 < MIN_SAFE_INTEGER || self.0 > MAX_SAFE_INTEGER {
447 bail!("numberic value outside of safe integer range for bitwise operation");453 bail!("numberic value outside of safe integer range for bitwise operation");
448 }454 }
455 #[expect(clippy::cast_possible_truncation, reason = "intended")]
449 Ok(self.0 as i64)456 Ok(self.0 as i64)
450 }457 }
451}458}
520 type Error = ConvertNumValueError;527 type Error = ConvertNumValueError;
521 #[inline]528 #[inline]
522 fn try_from(value: $ty) -> Result<Self, ConvertNumValueError> {529 fn try_from(value: $ty) -> Result<Self, ConvertNumValueError> {
530 #[expect(clippy::cast_precision_loss, reason = "precision loss is explicitly handled")]
523 let value = value as f64;531 let value = value as f64;
524 if value < MIN_SAFE_INTEGER {532 if value < MIN_SAFE_INTEGER {
525 return Err(ConvertNumValueError::Underflow)533 return Err(ConvertNumValueError::Underflow)
modifiedcrates/jrsonnet-interner/src/inner.rsdiffbeforeafterboth
67 .cast();67 .cast();
68 assert!(!data.is_null());68 assert!(!data.is_null());
69 *data = InnerHeader::new(bytes.len().try_into().expect("bytes > 4GB"), is_utf8);69 *data = InnerHeader::new(bytes.len().try_into().expect("bytes > 4GB"), is_utf8);
70 ptr::copy_nonoverlapping(bytes.as_ptr(), data.offset(1).cast::<u8>(), bytes.len());70 ptr::copy_nonoverlapping(bytes.as_ptr(), data.add(1).cast::<u8>(), bytes.len());
71 Self(UnsafeCell::new(NonNull::new_unchecked(data)))71 Self(UnsafeCell::new(NonNull::new_unchecked(data)))
72 }72 }
73 }73 }
89 let size = unsafe { (*header).size };89 let size = unsafe { (*header).size };
90 // SAFETY: bytes after data is allocated to be exactly data.size in length90 // SAFETY: bytes after data is allocated to be exactly data.size in length
91 unsafe {91 unsafe {
92 slice::from_raw_parts(92 slice::from_raw_parts((*self.0.get()).as_ptr().add(1).cast::<u8>(), size as usize)
93 (*self.0.get()).as_ptr().offset(1).cast::<u8>(),
94 size as usize,
95 )
96 }93 }
156 }153 }
157 pub fn as_ptr(this: &Self) -> *const u8 {154 pub fn as_ptr(this: &Self) -> *const u8 {
158 // SAFETY: data is initialized155 // SAFETY: data is initialized
159 unsafe { (*this.0.get()).as_ptr().offset(1).cast() }156 unsafe { (*this.0.get()).as_ptr().add(1).cast() }
160 }157 }
161158
162 pub fn strong_count(this: &Self) -> u32 {159 pub fn strong_count(this: &Self) -> u32 {
modifiedcrates/jrsonnet-ir-parser/src/lib.rsdiffbeforeafterboth
638 }638 }
639}639}
640640
641#[allow(clippy::too_many_lines)]
641fn expr_basic(p: &mut Parser<'_>) -> Result<Expr> {642fn expr_basic(p: &mut Parser<'_>) -> Result<Expr> {
642 if let Some(lit) = literal(p) {643 if let Some(lit) = literal(p) {
643 return Ok(Expr::Literal(lit));644 return Ok(Expr::Literal(lit));
764 }765 }
765766
766 SyntaxKind::IDENT => {767 SyntaxKind::IDENT => {
767 let text = p.text();
768 let n = spanned(p, |p| {768 let n = spanned(p, |p| {
769 let s: IStr = p.text().into();769 let s: IStr = p.text().into();
770 p.eat_any();770 p.eat_any();
1005}1005}
10061006
1007pub fn string_to_expr(s: IStr, settings: &ParserSettings) -> Spanned<Expr> {1007pub fn string_to_expr(s: IStr, settings: &ParserSettings) -> Spanned<Expr> {
1008 let len = s.len();1008 let len = u32::try_from(s.len()).expect("code size is limited by 4gb");
1009
1009 Spanned::new(Expr::Str(s), Span(settings.source.clone(), 0, len as u32))1010 Spanned::new(Expr::Str(s), Span(settings.source.clone(), 0, len))
1010}1011}
10111012
1012#[cfg(test)]1013#[cfg(test)]
modifiedcrates/jrsonnet-lexer/src/lex.rsdiffbeforeafterboth
60 range: {60 range: {
61 let Range { start, end } = self.inner.span();61 let Range { start, end } = self.inner.span();
6262
63 Span(start as u32, end as u32)63 Span(
64 u32::try_from(start).expect("code size is limited by 4gb"),
65 u32::try_from(end).expect("code size is limited by 4gb"),
66 )
64 },67 },
65 })68 })
modifiedcrates/jrsonnet-stdlib/src/arrays.rsdiffbeforeafterboth
1818
19#[builtin]19#[builtin]
20pub fn builtin_make_array(sz: BoundedI32<0, { i32::MAX }>, func: FuncVal) -> Result<ArrValue> {20pub fn builtin_make_array(
21 // Can't use usize because range_exclusive is over i32
22 sz: BoundedI32<0, { i32::MAX }>,
23 func: FuncVal,
24) -> Result<ArrValue> {
21 if *sz == 0 {25 if *sz == 0 {
22 return Ok(ArrValue::empty());26 return Ok(ArrValue::empty());
25 // TODO: Different mapped array impl avoiding allocating unnecessary vals29 // TODO: Different mapped array impl avoiding allocating unnecessary vals
26 || Ok(ArrValue::range_exclusive(0, *sz).map(FromUntyped::from_untyped(Val::Func(func))?)),30 || Ok(ArrValue::range_exclusive(0, *sz).map(FromUntyped::from_untyped(Val::Func(func))?)),
27 |trivial| {31 |trivial| {
32 #[expect(clippy::cast_sign_loss, reason = "sz is bounded to be larger than 0")]
28 let mut out = Vec::with_capacity(*sz as usize);33 let mut out = Vec::with_capacity(*sz as usize);
29 for _ in 0..*sz {34 for _ in 0..*sz {
30 out.push(trivial.clone());35 out.push(trivial.clone());
363 if arr.is_empty() {368 if arr.is_empty() {
364 return eval_on_empty(onEmpty);369 return eval_on_empty(onEmpty);
365 }370 }
371 #[expect(
372 clippy::cast_precision_loss,
373 reason = "array sizes are bounded to i32 len"
374 )]
366 Ok(Val::try_num(arr.iter().sum::<f64>() / (arr.len() as f64))?)375 Ok(Val::try_num(arr.iter().sum::<f64>() / (arr.len() as f64))?)
367}376}
368377
378pub fn builtin_remove(arr: ArrValue, elem: Val) -> Result<ArrValue> {387pub fn builtin_remove(arr: ArrValue, elem: Val) -> Result<ArrValue> {
379 for (index, item) in arr.iter().enumerate() {388 for (index, item) in arr.iter().enumerate() {
380 if equals(&item?, &elem)? {389 if equals(&item?, &elem)? {
390 #[expect(
391 clippy::cast_possible_truncation,
392 clippy::cast_possible_wrap,
393 reason = "array sizes are bounded to i32 len"
394 )]
381 return builtin_remove_at(arr.clone(), index as i32);395 return builtin_remove_at(arr.clone(), index as i32);
382 }396 }
383 }397 }
modifiedcrates/jrsonnet-stdlib/src/math.rsdiffbeforeafterboth
120 let lg = s.abs().log2();120 let lg = s.abs().log2();
121 let x = (lg - lg.floor() - 1.0).exp2();121 let x = (lg - lg.floor() - 1.0).exp2();
122 let exp = lg.floor() + 1.0;122 let exp = lg.floor() + 1.0;
123 #[expect(clippy::cast_possible_truncation, reason = "exponent can fit in i16")]
123 (s.signum() * x, exp as i16)124 (s.signum() * x, exp as i16)
124 }125 }
125}126}
modifiedflake.nixdiffbeforeafterboth
66 "clippy"66 "clippy"
67 "rustc"67 "rustc"
68 "rust-src"68 "rust-src"
69 "rust-analyzer"
69 ])70 ])
70 rustfmt71 rustfmt
71 ];72 ];