difftreelog
refactor reenable clippy integer cast checks
in: master
17 files changed
Cargo.tomldiffbeforeafterboth--- a/Cargo.toml
+++ b/Cargo.toml
@@ -122,11 +122,6 @@
wildcard_imports = "allow"
enum_glob_use = "allow"
module_name_repetitions = "allow"
-# TODO: fix individual issues, however this works as intended almost everywhere
-cast_precision_loss = "allow"
-cast_possible_wrap = "allow"
-cast_possible_truncation = "allow"
-cast_sign_loss = "allow"
# False positives
# https://github.com/rust-lang/rust-clippy/issues/6902
use_self = "allow"
crates/jrsonnet-evaluator/src/arr/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/arr/mod.rs
+++ b/crates/jrsonnet-evaluator/src/arr/mod.rs
@@ -128,7 +128,12 @@
#[must_use]
pub fn slice(self, index: Option<i32>, end: Option<i32>, step: Option<NonZeroU32>) -> Self {
let get_idx = |pos: Option<i32>, len: usize, default| match pos {
+ #[expect(
+ clippy::cast_sign_loss,
+ reason = "abs value is used, len is limited to u31"
+ )]
Some(v) if v < 0 => len.saturating_sub((-v) as usize),
+ #[expect(clippy::cast_sign_loss, reason = "abs value is used")]
Some(v) => (v as usize).min(len),
None => default,
};
@@ -142,7 +147,9 @@
Self::new(SliceArray {
inner: self,
+ #[expect(clippy::cast_possible_truncation, reason = "len is limited to u31")]
from: index as u32,
+ #[expect(clippy::cast_possible_truncation, reason = "len is limited to u31")]
to: end as u32,
step: step.get(),
})
crates/jrsonnet-evaluator/src/arr/spec.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/arr/spec.rs
+++ b/crates/jrsonnet-evaluator/src/arr/spec.rs
@@ -350,22 +350,26 @@
pub fn new_inclusive(start: i32, end: i32) -> Self {
Self { start, end }
}
+ #[expect(
+ clippy::cast_sign_loss,
+ reason = "the math is valid with wrapping, sign loss works as intended"
+ )]
+ fn size(&self) -> usize {
+ (self.end as usize)
+ .wrapping_sub(self.start as usize)
+ .wrapping_add(1)
+ }
fn range(&self) -> impl ExactSizeIterator<Item = i32> + DoubleEndedIterator {
- WithExactSize(
- self.start..=self.end,
- (self.end as usize)
- .wrapping_sub(self.start as usize)
- .wrapping_add(1),
- )
+ WithExactSize(self.start..=self.end, self.size())
}
}
impl ArrayLike for RangeArray {
fn len(&self) -> usize {
- self.range().len()
+ self.size()
}
fn is_empty(&self) -> bool {
- self.range().len() == 0
+ self.size() == 0
}
fn get(&self, index: usize) -> Result<Option<Val>> {
@@ -431,6 +435,10 @@
fn evaluate(&self, index: usize, value: Val) -> Result<Val> {
match &self.mapper {
ArrayMapper::Plain(f) => f.call(value),
+ #[expect(
+ clippy::cast_possible_truncation,
+ reason = "array len is limited to u31"
+ )]
ArrayMapper::WithIndex(f) => f.call(index as u32, value),
}
}
crates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/evaluate/mod.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/mod.rs
@@ -548,8 +548,18 @@
bail!(FractionalIndex)
}
if n < 0.0 {
- bail!(ArrayBoundsError(n as isize, v.len()));
+ #[expect(
+ clippy::cast_possible_truncation,
+ reason = "it would be truncated anyway"
+ )]
+ let n = n as isize;
+ bail!(ArrayBoundsError(n, v.len()));
}
+ #[expect(
+ clippy::cast_possible_truncation,
+ clippy::cast_sign_loss,
+ reason = "n is checked postive"
+ )]
v.get(n as usize)?
.ok_or_else(|| ArrayBoundsError(n as isize, v.len()))?
}
@@ -568,18 +578,29 @@
bail!(FractionalIndex)
}
if n < 0.0 {
- bail!(ArrayBoundsError(n as isize, s.into_flat().chars().count()));
+ #[expect(
+ clippy::cast_possible_truncation,
+ reason = "it would be truncated anyway"
+ )]
+ let n = n as isize;
+ bail!(ArrayBoundsError(n, s.into_flat().chars().count()));
}
+ #[expect(
+ clippy::cast_sign_loss,
+ clippy::cast_possible_truncation,
+ reason = "n is positive, overflow will truncate as expected"
+ )]
+ let n = n as usize;
let v: IStr = s
.clone()
.into_flat()
.chars()
- .skip(n as usize)
+ .skip(n)
.take(1)
.collect::<String>()
.into();
if v.is_empty() {
- bail!(StringBoundsError(n as usize, s.into_flat().chars().count()))
+ bail!(StringBoundsError(n, s.into_flat().chars().count()))
}
StrValue::Flat(v)
}),
crates/jrsonnet-evaluator/src/evaluate/operator.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/evaluate/operator.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/operator.rs
@@ -20,7 +20,8 @@
(Plus, Num(n)) => Val::Num(*n),
(Minus, Num(n)) => Val::try_num(-n.get())?,
(Not, Bool(v)) => Bool(!v),
- (BitNot, Num(n)) => Val::try_num(!(n.get() as i64) as f64)?,
+ #[expect(clippy::cast_precision_loss, reason = "as spec")]
+ (BitNot, Num(n)) => Val::try_num(!n.truncate_for_bitwise()? as f64)?,
(op, o) => bail!(UnaryOperatorDoesNotOperateOnType(op, o.value_type())),
})
}
@@ -73,7 +74,17 @@
pub fn evaluate_mul_op(a: &Val, b: &Val) -> Result<Val> {
use Val::*;
Ok(match (a, b) {
+ #[expect(
+ clippy::cast_possible_truncation,
+ clippy::cast_sign_loss,
+ reason = "should not be used with values too large, negative == 0"
+ )]
(Str(s), Num(c)) => Val::string(s.to_string().repeat(c.get() as usize)),
+ #[expect(
+ clippy::cast_possible_truncation,
+ clippy::cast_sign_loss,
+ reason = "should not be used with values too large"
+ )]
(Num(c), Str(s)) => Val::string(s.to_string().repeat(c.get() as usize)),
(Num(v1), Num(v2)) => Val::try_num(v1.get() * v2.get())?,
@@ -218,13 +229,28 @@
(a, Div, b) => evaluate_div_op(a, b)?,
(a, Mod, b) => evaluate_mod_op(a, b)?,
- (Num(v1), BitAnd, Num(v2)) => {
+ (Num(v1), BitAnd, Num(v2)) =>
+ {
+ #[expect(
+ clippy::cast_precision_loss,
+ reason = "values are within safe integer ranges"
+ )]
Val::try_num((v1.truncate_for_bitwise()? & v2.truncate_for_bitwise()?) as f64)?
}
- (Num(v1), BitOr, Num(v2)) => {
+ (Num(v1), BitOr, Num(v2)) =>
+ {
+ #[expect(
+ clippy::cast_precision_loss,
+ reason = "values are within safe integer ranges"
+ )]
Val::try_num((v1.truncate_for_bitwise()? | v2.truncate_for_bitwise()?) as f64)?
}
- (Num(v1), BitXor, Num(v2)) => {
+ (Num(v1), BitXor, Num(v2)) =>
+ {
+ #[expect(
+ clippy::cast_precision_loss,
+ reason = "values are within safe integer ranges"
+ )]
Val::try_num((v1.truncate_for_bitwise()? ^ v2.truncate_for_bitwise()?) as f64)?
}
(Num(v1), Lhs, Num(v2)) => {
@@ -234,16 +260,28 @@
let base = v1.truncate_for_bitwise()?;
let exp = v2.truncate_for_bitwise()? % 64;
+ #[expect(clippy::cast_sign_loss, reason = "exp is positive")]
if exp >= 1 && base >= (1i64 << (63 - exp as u32)) {
bail!("left shift would overflow")
}
+ #[expect(
+ clippy::cast_precision_loss,
+ clippy::cast_sign_loss,
+ reason = "checked as original impl"
+ )]
Val::try_num(base.wrapping_shl(exp as u32) as f64)?
}
(Num(v1), Rhs, Num(v2)) => {
if v2.get() < 0.0 {
bail!("shift by negative exponent")
}
+ #[expect(
+ clippy::cast_sign_loss,
+ clippy::cast_possible_truncation,
+ reason = "checked as original impl"
+ )]
let exp = ((v2.get() as i64) & 63) as u32;
+ #[expect(clippy::cast_precision_loss, reason = "checked as upstream impl")]
Val::try_num(v1.truncate_for_bitwise()?.wrapping_shr(exp) as f64)?
}
crates/jrsonnet-evaluator/src/integrations/serde.rsdiffbeforeafterboth1use std::borrow::Cow;23use jrsonnet_interner::IStr;4use serde::{5 Deserialize, Serialize, Serializer,6 de::{self, Visitor},7 ser::{8 Error, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,9 SerializeTupleStruct, SerializeTupleVariant,10 },11};1213use crate::{14 Error as JrError, ObjValue, ObjValueBuilder, Result, Val, arr::ArrValue, in_description_frame,15 runtime_error, val::NumValue,16};1718impl<'de> Deserialize<'de> for Val {19 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>20 where21 D: serde::Deserializer<'de>,22 {23 struct ValVisitor;2425 // macro_rules! visit_num {26 // ($($method:ident => $ty:ty),* $(,)?) => {$(27 // fn $method<E>(self, v: $ty) -> Result<Self::Value, E>28 // where29 // E: serde::de::Error,30 // {31 // Ok(Val::Num(f64::from(v)))32 // }33 // )*};34 // }3536 impl<'de> Visitor<'de> for ValVisitor {37 type Value = Val;3839 fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>40 where41 E: de::Error,42 {43 Ok(Val::Bool(v))44 }45 fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>46 where47 E: de::Error,48 {49 Ok(Val::Num(NumValue::new(v).ok_or_else(|| {50 E::custom("only finite numbers are supported")51 })?))52 }53 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>54 where55 E: de::Error,56 {57 Ok(Val::string(v))58 }5960 // visit_num! {61 // visit_i8 => i8,62 // visit_i16 => i16,63 // visit_i32 => i32,64 // visit_u8 => u8,65 // visit_u16 => u16,66 // visit_u32 => u32,67 // }68 fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>69 where70 E: de::Error,71 {72 Ok(Val::Num(NumValue::new(v as f64).expect("no overflow")))73 }74 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>75 where76 E: de::Error,77 {78 Ok(Val::Num(NumValue::new(v as f64).expect("no overflow")))79 }8081 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>82 where83 E: de::Error,84 {85 Ok(Val::Arr(ArrValue::bytes(v.into())))86 }8788 fn visit_none<E>(self) -> Result<Self::Value, E>89 where90 E: de::Error,91 {92 Ok(Val::Null)93 }94 fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>95 where96 D: serde::Deserializer<'de>,97 {98 deserializer.deserialize_any(self)99 }100101 fn visit_unit<E>(self) -> Result<Self::Value, E>102 where103 E: de::Error,104 {105 Ok(Val::Null)106 }107108 fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>109 where110 D: serde::Deserializer<'de>,111 {112 deserializer.deserialize_any(self)113 }114115 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>116 where117 A: de::SeqAccess<'de>,118 {119 let mut out = seq.size_hint().map_or_else(Vec::new, Vec::with_capacity);120121 while let Some(val) = seq.next_element::<Val>()? {122 out.push(val);123 }124125 Ok(Val::Arr(ArrValue::eager(out)))126 }127128 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>129 where130 A: de::MapAccess<'de>,131 {132 let mut out = map133 .size_hint()134 .map_or_else(ObjValueBuilder::new, ObjValueBuilder::with_capacity);135136 while let Some((k, v)) = map.next_entry::<Cow<'de, str>, Val>()? {137 // Jsonnet ignores duplicate keys138 out.field(k).value(v);139 }140141 Ok(Val::Obj(out.build()))142 }143144 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {145 write!(formatter, "any valid jsonnet value")146 }147 }148 deserializer.deserialize_any(ValVisitor)149 }150}151152impl Serialize for Val {153 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>154 where155 S: serde::Serializer,156 {157 match self {158 Self::Bool(v) => serializer.serialize_bool(*v),159 Self::Null => serializer.serialize_none(),160 Self::Str(s) => serializer.serialize_str(&s.clone().into_flat()),161 Self::Num(n) => {162 let n = n.get();163 if n.fract() == 0.0 {164 let n = n as i64;165 serializer.serialize_i64(n)166 } else {167 serializer.serialize_f64(n)168 }169 }170 #[cfg(feature = "exp-bigint")]171 Self::BigInt(b) => b.serialize(serializer),172 Self::Arr(arr) => {173 let mut seq = serializer.serialize_seq(Some(arr.len()))?;174 for (i, element) in arr.iter().enumerate() {175 let mut serde_error = None;176 in_description_frame(177 || format!("array index [{i}]"),178 || {179 let e = element?;180 if let Err(e) = seq.serialize_element(&e) {181 serde_error = Some(e);182 }183 Ok(())184 },185 )186 .map_err(|e| S::Error::custom(e.to_string()))?;187 if let Some(e) = serde_error {188 return Err(e);189 }190 }191 seq.end()192 }193 Self::Obj(obj) => {194 let mut map = serializer.serialize_map(Some(obj.len()))?;195 for (field, value) in obj.iter(196 #[cfg(feature = "exp-preserve-order")]197 true,198 ) {199 let mut serde_error = None;200 // TODO: rewrite using try{} after stabilization201 in_description_frame(202 || format!("object field {field:?}"),203 || {204 let v = value?;205 if let Err(e) = map.serialize_entry(field.as_str(), &v) {206 serde_error = Some(e);207 }208 Ok(())209 },210 )211 .map_err(|e| S::Error::custom(e.to_string()))?;212 if let Some(e) = serde_error {213 return Err(e);214 }215 }216 map.end()217 }218 Self::Func(_) => Err(S::Error::custom("tried to manifest function")),219 }220 }221}222223struct IntoVecValSerializer {224 variant: Option<IStr>,225 data: Vec<Val>,226}227impl IntoVecValSerializer {228 fn new() -> Self {229 Self {230 variant: None,231 data: Vec::new(),232 }233 }234 fn with_capacity(capacity: usize) -> Self {235 Self {236 variant: None,237 data: Vec::with_capacity(capacity),238 }239 }240 fn variant_with_capacity(variant: impl Into<IStr>, capacity: usize) -> Self {241 Self {242 variant: Some(variant.into()),243 data: Vec::with_capacity(capacity),244 }245 }246}247impl SerializeSeq for IntoVecValSerializer {248 type Ok = Val;249 type Error = JrError;250251 fn serialize_element<T>(&mut self, value: &T) -> Result<()>252 where253 T: ?Sized + Serialize,254 {255 let value = value.serialize(IntoValSerializer)?;256 self.data.push(value);257 Ok(())258 }259260 fn end(self) -> Result<Val> {261 let inner = Val::Arr(ArrValue::eager(self.data));262 if let Some(variant) = self.variant {263 let mut out = ObjValue::builder_with_capacity(1);264 out.field(variant).value(inner);265 Ok(Val::Obj(out.build()))266 } else {267 Ok(inner)268 }269 }270}271impl SerializeTuple for IntoVecValSerializer {272 type Ok = Val;273 type Error = JrError;274275 fn serialize_element<T>(&mut self, value: &T) -> Result<()>276 where277 T: ?Sized + Serialize,278 {279 SerializeSeq::serialize_element(self, value)280 }281282 fn end(self) -> Result<Val> {283 SerializeSeq::end(self)284 }285}286impl SerializeTupleVariant for IntoVecValSerializer {287 type Ok = Val;288 type Error = JrError;289290 fn serialize_field<T>(&mut self, value: &T) -> Result<()>291 where292 T: ?Sized + Serialize,293 {294 SerializeSeq::serialize_element(self, value)295 }296297 fn end(self) -> Result<Val> {298 SerializeSeq::end(self)299 }300}301impl SerializeTupleStruct for IntoVecValSerializer {302 type Ok = Val;303 type Error = JrError;304305 fn serialize_field<T>(&mut self, value: &T) -> Result<()>306 where307 T: ?Sized + Serialize,308 {309 SerializeSeq::serialize_element(self, value)310 }311312 fn end(self) -> Result<Val> {313 SerializeSeq::end(self)314 }315}316317struct IntoObjValueSerializer {318 variant: Option<IStr>,319 data: ObjValueBuilder,320 key: Option<IStr>,321}322impl IntoObjValueSerializer {323 fn new() -> Self {324 Self {325 variant: None,326 data: ObjValue::builder(),327 key: None,328 }329 }330 fn with_capacity(capacity: usize) -> Self {331 Self {332 variant: None,333 data: ObjValue::builder_with_capacity(capacity),334 key: None,335 }336 }337 fn variant_with_capacity(variant: impl Into<IStr>, capacity: usize) -> Self {338 Self {339 variant: Some(variant.into()),340 data: ObjValue::builder_with_capacity(capacity),341 key: None,342 }343 }344}345impl SerializeMap for IntoObjValueSerializer {346 type Ok = Val;347 type Error = JrError;348349 fn serialize_key<T>(&mut self, key: &T) -> Result<()>350 where351 T: ?Sized + Serialize,352 {353 let key = key.serialize(IntoValSerializer)?;354 let key = key.to_string()?;355 self.key = Some(key);356 Ok(())357 }358359 fn serialize_value<T>(&mut self, value: &T) -> Result<()>360 where361 T: ?Sized + Serialize,362 {363 let key = self.key.take().expect("no serialize_key called");364 let value = value.serialize(IntoValSerializer)?;365 self.data.field(key).try_value(value)?;366 Ok(())367 }368369 // TODO: serialize_key/serialize_value370 fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<()>371 where372 K: ?Sized + Serialize,373 V: ?Sized + Serialize,374 {375 let key = key.serialize(IntoValSerializer)?;376 let key = key.to_string()?;377 let value = value.serialize(IntoValSerializer)?;378 self.data.field(key).try_value(value)?;379 Ok(())380 }381382 fn end(self) -> Result<Val> {383 let inner = Val::Obj(self.data.build());384 if let Some(variant) = self.variant {385 let mut out = ObjValue::builder_with_capacity(1);386 out.field(variant).value(inner);387 Ok(Val::Obj(out.build()))388 } else {389 Ok(inner)390 }391 }392}393impl SerializeStruct for IntoObjValueSerializer {394 type Ok = Val;395 type Error = JrError;396397 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>398 where399 T: ?Sized + Serialize,400 {401 SerializeMap::serialize_entry(self, key, value)?;402 Ok(())403 }404405 fn end(self) -> Result<Val> {406 SerializeMap::end(self)407 }408}409impl SerializeStructVariant for IntoObjValueSerializer {410 type Ok = Val;411412 type Error = JrError;413414 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>415 where416 T: ?Sized + Serialize,417 {418 SerializeMap::serialize_entry(self, key, value)?;419 Ok(())420 }421422 fn end(self) -> Result<Val> {423 SerializeMap::end(self)424 }425}426427struct IntoValSerializer;428impl Serializer for IntoValSerializer {429 type Ok = Val;430431 type Error = JrError;432433 type SerializeSeq = IntoVecValSerializer;434435 type SerializeTuple = IntoVecValSerializer;436437 type SerializeTupleStruct = IntoVecValSerializer;438439 type SerializeTupleVariant = IntoVecValSerializer;440441 type SerializeMap = IntoObjValueSerializer;442443 type SerializeStruct = IntoObjValueSerializer;444445 type SerializeStructVariant = IntoObjValueSerializer;446447 fn serialize_bool(self, v: bool) -> Result<Val> {448 Ok(Val::Bool(v))449 }450451 fn serialize_i8(self, v: i8) -> Result<Val> {452 Ok(Val::Num(v.into()))453 }454455 fn serialize_i16(self, v: i16) -> Result<Val> {456 Ok(Val::Num(v.into()))457 }458459 fn serialize_i32(self, v: i32) -> Result<Val> {460 Ok(Val::Num(v.into()))461 }462463 fn serialize_i64(self, v: i64) -> Result<Val> {464 Ok(Val::Str(v.to_string().into()))465 }466467 fn serialize_u8(self, v: u8) -> Result<Val> {468 Ok(Val::Num(v.into()))469 }470471 fn serialize_u16(self, v: u16) -> Result<Val> {472 Ok(Val::Num(v.into()))473 }474475 fn serialize_u32(self, v: u32) -> Result<Val> {476 Ok(Val::Num(v.into()))477 }478479 fn serialize_u64(self, v: u64) -> Result<Val> {480 Ok(Val::Str(v.to_string().into()))481 }482483 fn serialize_f32(self, v: f32) -> Result<Val> {484 Ok(Val::try_num(f64::from(v))?)485 }486487 fn serialize_f64(self, v: f64) -> Result<Val> {488 Ok(Val::try_num(v)?)489 }490491 fn serialize_char(self, v: char) -> Result<Val> {492 Ok(Val::Str(v.to_string().into()))493 }494495 fn serialize_str(self, v: &str) -> Result<Val> {496 Ok(Val::Str(v.into()))497 }498499 fn serialize_bytes(self, v: &[u8]) -> Result<Val> {500 Ok(Val::Arr(ArrValue::bytes(v.into())))501 }502503 fn serialize_none(self) -> Result<Val> {504 Ok(Val::Null)505 }506507 fn serialize_some<T>(self, value: &T) -> Result<Val>508 where509 T: ?Sized + Serialize,510 {511 value.serialize(self)512 }513514 fn serialize_unit(self) -> Result<Val> {515 Ok(Val::Null)516 }517518 fn serialize_unit_struct(self, _name: &'static str) -> Result<Val> {519 Ok(Val::Null)520 }521522 fn serialize_unit_variant(523 self,524 _name: &'static str,525 _variant_index: u32,526 variant: &'static str,527 ) -> Result<Val> {528 Ok(Val::Str(variant.into()))529 }530531 fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<Val>532 where533 T: ?Sized + Serialize,534 {535 value.serialize(self)536 }537538 fn serialize_newtype_variant<T>(539 self,540 _name: &'static str,541 _variant_index: u32,542 variant: &'static str,543 value: &T,544 ) -> Result<Val>545 where546 T: ?Sized + Serialize,547 {548 let mut out = ObjValue::builder_with_capacity(1);549 let value = value.serialize(self)?;550 out.field(variant).value(value);551 Ok(Val::Obj(out.build()))552 }553554 fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {555 Ok(len.map_or_else(556 IntoVecValSerializer::new,557 IntoVecValSerializer::with_capacity,558 ))559 }560561 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {562 Ok(IntoVecValSerializer::with_capacity(len))563 }564565 fn serialize_tuple_struct(566 self,567 _name: &'static str,568 len: usize,569 ) -> Result<Self::SerializeTupleStruct, Self::Error> {570 Ok(IntoVecValSerializer::with_capacity(len))571 }572573 fn serialize_tuple_variant(574 self,575 _name: &'static str,576 _variant_index: u32,577 variant: &'static str,578 len: usize,579 ) -> Result<Self::SerializeTupleVariant, Self::Error> {580 Ok(IntoVecValSerializer::variant_with_capacity(variant, len))581 }582583 fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {584 Ok(len.map_or_else(585 IntoObjValueSerializer::new,586 IntoObjValueSerializer::with_capacity,587 ))588 }589590 fn serialize_struct(591 self,592 _name: &'static str,593 len: usize,594 ) -> Result<Self::SerializeStruct, Self::Error> {595 Ok(IntoObjValueSerializer::with_capacity(len))596 }597598 fn serialize_struct_variant(599 self,600 _name: &'static str,601 _variant_index: u32,602 variant: &'static str,603 len: usize,604 ) -> Result<Self::SerializeStructVariant, Self::Error> {605 Ok(IntoObjValueSerializer::variant_with_capacity(variant, len))606 }607}608609impl Val {610 pub fn from_serde(v: impl Serialize) -> Result<Self, JrError> {611 v.serialize(IntoValSerializer)612 }613}614615impl serde::ser::Error for JrError {616 fn custom<T>(msg: T) -> Self617 where618 T: std::fmt::Display,619 {620 runtime_error!("serde: {msg}")621 }622}1use std::borrow::Cow;23use jrsonnet_interner::IStr;4use serde::{5 Deserialize, Serialize, Serializer,6 de::{self, Visitor},7 ser::{8 Error, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,9 SerializeTupleStruct, SerializeTupleVariant,10 },11};1213use crate::{14 Error as JrError, ObjValue, ObjValueBuilder, Result, Val, arr::ArrValue, in_description_frame,15 runtime_error, val::NumValue,16};1718impl<'de> Deserialize<'de> for Val {19 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>20 where21 D: serde::Deserializer<'de>,22 {23 struct ValVisitor;2425 // macro_rules! visit_num {26 // ($($method:ident => $ty:ty),* $(,)?) => {$(27 // fn $method<E>(self, v: $ty) -> Result<Self::Value, E>28 // where29 // E: serde::de::Error,30 // {31 // Ok(Val::Num(f64::from(v)))32 // }33 // )*};34 // }3536 impl<'de> Visitor<'de> for ValVisitor {37 type Value = Val;3839 fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>40 where41 E: de::Error,42 {43 Ok(Val::Bool(v))44 }45 fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>46 where47 E: de::Error,48 {49 Ok(Val::Num(NumValue::new(v).ok_or_else(|| {50 E::custom("only finite numbers are supported")51 })?))52 }53 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>54 where55 E: de::Error,56 {57 Ok(Val::string(v))58 }5960 // visit_num! {61 // visit_i8 => i8,62 // visit_i16 => i16,63 // visit_i32 => i32,64 // visit_u8 => u8,65 // visit_u16 => u16,66 // visit_u32 => u32,67 // }68 fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>69 where70 E: de::Error,71 {72 #[expect(73 clippy::cast_precision_loss,74 reason = "this is how it works with stdlib functions"75 )]76 Ok(Val::Num(NumValue::new(v as f64).expect("no overflow")))77 }78 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>79 where80 E: de::Error,81 {82 #[expect(83 clippy::cast_precision_loss,84 reason = "this is how it works with stdlib functions"85 )]86 Ok(Val::Num(NumValue::new(v as f64).expect("no overflow")))87 }8889 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>90 where91 E: de::Error,92 {93 Ok(Val::Arr(ArrValue::bytes(v.into())))94 }9596 fn visit_none<E>(self) -> Result<Self::Value, E>97 where98 E: de::Error,99 {100 Ok(Val::Null)101 }102 fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>103 where104 D: serde::Deserializer<'de>,105 {106 deserializer.deserialize_any(self)107 }108109 fn visit_unit<E>(self) -> Result<Self::Value, E>110 where111 E: de::Error,112 {113 Ok(Val::Null)114 }115116 fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>117 where118 D: serde::Deserializer<'de>,119 {120 deserializer.deserialize_any(self)121 }122123 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>124 where125 A: de::SeqAccess<'de>,126 {127 let mut out = seq.size_hint().map_or_else(Vec::new, Vec::with_capacity);128129 while let Some(val) = seq.next_element::<Val>()? {130 out.push(val);131 }132133 Ok(Val::Arr(ArrValue::eager(out)))134 }135136 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>137 where138 A: de::MapAccess<'de>,139 {140 let mut out = map141 .size_hint()142 .map_or_else(ObjValueBuilder::new, ObjValueBuilder::with_capacity);143144 while let Some((k, v)) = map.next_entry::<Cow<'de, str>, Val>()? {145 // Jsonnet ignores duplicate keys146 out.field(k).value(v);147 }148149 Ok(Val::Obj(out.build()))150 }151152 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {153 write!(formatter, "any valid jsonnet value")154 }155 }156 deserializer.deserialize_any(ValVisitor)157 }158}159160impl Serialize for Val {161 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>162 where163 S: serde::Serializer,164 {165 match self {166 Self::Bool(v) => serializer.serialize_bool(*v),167 Self::Null => serializer.serialize_none(),168 Self::Str(s) => serializer.serialize_str(&s.clone().into_flat()),169 Self::Num(n) => {170 let n = n.get();171 if n.fract() == 0.0 {172 #[expect(173 clippy::cast_possible_truncation,174 reason = "no correct implementation is possible here; expected"175 )]176 let n = n as i64;177 serializer.serialize_i64(n)178 } else {179 serializer.serialize_f64(n)180 }181 }182 #[cfg(feature = "exp-bigint")]183 Self::BigInt(b) => b.serialize(serializer),184 Self::Arr(arr) => {185 let mut seq = serializer.serialize_seq(Some(arr.len()))?;186 for (i, element) in arr.iter().enumerate() {187 let mut serde_error = None;188 in_description_frame(189 || format!("array index [{i}]"),190 || {191 let e = element?;192 if let Err(e) = seq.serialize_element(&e) {193 serde_error = Some(e);194 }195 Ok(())196 },197 )198 .map_err(|e| S::Error::custom(e.to_string()))?;199 if let Some(e) = serde_error {200 return Err(e);201 }202 }203 seq.end()204 }205 Self::Obj(obj) => {206 let mut map = serializer.serialize_map(Some(obj.len()))?;207 for (field, value) in obj.iter(208 #[cfg(feature = "exp-preserve-order")]209 true,210 ) {211 let mut serde_error = None;212 // TODO: rewrite using try{} after stabilization213 in_description_frame(214 || format!("object field {field:?}"),215 || {216 let v = value?;217 if let Err(e) = map.serialize_entry(field.as_str(), &v) {218 serde_error = Some(e);219 }220 Ok(())221 },222 )223 .map_err(|e| S::Error::custom(e.to_string()))?;224 if let Some(e) = serde_error {225 return Err(e);226 }227 }228 map.end()229 }230 Self::Func(_) => Err(S::Error::custom("tried to manifest function")),231 }232 }233}234235struct IntoVecValSerializer {236 variant: Option<IStr>,237 data: Vec<Val>,238}239impl IntoVecValSerializer {240 fn new() -> Self {241 Self {242 variant: None,243 data: Vec::new(),244 }245 }246 fn with_capacity(capacity: usize) -> Self {247 Self {248 variant: None,249 data: Vec::with_capacity(capacity),250 }251 }252 fn variant_with_capacity(variant: impl Into<IStr>, capacity: usize) -> Self {253 Self {254 variant: Some(variant.into()),255 data: Vec::with_capacity(capacity),256 }257 }258}259impl SerializeSeq for IntoVecValSerializer {260 type Ok = Val;261 type Error = JrError;262263 fn serialize_element<T>(&mut self, value: &T) -> Result<()>264 where265 T: ?Sized + Serialize,266 {267 let value = value.serialize(IntoValSerializer)?;268 self.data.push(value);269 Ok(())270 }271272 fn end(self) -> Result<Val> {273 let inner = Val::Arr(ArrValue::eager(self.data));274 if let Some(variant) = self.variant {275 let mut out = ObjValue::builder_with_capacity(1);276 out.field(variant).value(inner);277 Ok(Val::Obj(out.build()))278 } else {279 Ok(inner)280 }281 }282}283impl SerializeTuple for IntoVecValSerializer {284 type Ok = Val;285 type Error = JrError;286287 fn serialize_element<T>(&mut self, value: &T) -> Result<()>288 where289 T: ?Sized + Serialize,290 {291 SerializeSeq::serialize_element(self, value)292 }293294 fn end(self) -> Result<Val> {295 SerializeSeq::end(self)296 }297}298impl SerializeTupleVariant for IntoVecValSerializer {299 type Ok = Val;300 type Error = JrError;301302 fn serialize_field<T>(&mut self, value: &T) -> Result<()>303 where304 T: ?Sized + Serialize,305 {306 SerializeSeq::serialize_element(self, value)307 }308309 fn end(self) -> Result<Val> {310 SerializeSeq::end(self)311 }312}313impl SerializeTupleStruct for IntoVecValSerializer {314 type Ok = Val;315 type Error = JrError;316317 fn serialize_field<T>(&mut self, value: &T) -> Result<()>318 where319 T: ?Sized + Serialize,320 {321 SerializeSeq::serialize_element(self, value)322 }323324 fn end(self) -> Result<Val> {325 SerializeSeq::end(self)326 }327}328329struct IntoObjValueSerializer {330 variant: Option<IStr>,331 data: ObjValueBuilder,332 key: Option<IStr>,333}334impl IntoObjValueSerializer {335 fn new() -> Self {336 Self {337 variant: None,338 data: ObjValue::builder(),339 key: None,340 }341 }342 fn with_capacity(capacity: usize) -> Self {343 Self {344 variant: None,345 data: ObjValue::builder_with_capacity(capacity),346 key: None,347 }348 }349 fn variant_with_capacity(variant: impl Into<IStr>, capacity: usize) -> Self {350 Self {351 variant: Some(variant.into()),352 data: ObjValue::builder_with_capacity(capacity),353 key: None,354 }355 }356}357impl SerializeMap for IntoObjValueSerializer {358 type Ok = Val;359 type Error = JrError;360361 fn serialize_key<T>(&mut self, key: &T) -> Result<()>362 where363 T: ?Sized + Serialize,364 {365 let key = key.serialize(IntoValSerializer)?;366 let key = key.to_string()?;367 self.key = Some(key);368 Ok(())369 }370371 fn serialize_value<T>(&mut self, value: &T) -> Result<()>372 where373 T: ?Sized + Serialize,374 {375 let key = self.key.take().expect("no serialize_key called");376 let value = value.serialize(IntoValSerializer)?;377 self.data.field(key).try_value(value)?;378 Ok(())379 }380381 // TODO: serialize_key/serialize_value382 fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<()>383 where384 K: ?Sized + Serialize,385 V: ?Sized + Serialize,386 {387 let key = key.serialize(IntoValSerializer)?;388 let key = key.to_string()?;389 let value = value.serialize(IntoValSerializer)?;390 self.data.field(key).try_value(value)?;391 Ok(())392 }393394 fn end(self) -> Result<Val> {395 let inner = Val::Obj(self.data.build());396 if let Some(variant) = self.variant {397 let mut out = ObjValue::builder_with_capacity(1);398 out.field(variant).value(inner);399 Ok(Val::Obj(out.build()))400 } else {401 Ok(inner)402 }403 }404}405impl SerializeStruct for IntoObjValueSerializer {406 type Ok = Val;407 type Error = JrError;408409 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>410 where411 T: ?Sized + Serialize,412 {413 SerializeMap::serialize_entry(self, key, value)?;414 Ok(())415 }416417 fn end(self) -> Result<Val> {418 SerializeMap::end(self)419 }420}421impl SerializeStructVariant for IntoObjValueSerializer {422 type Ok = Val;423424 type Error = JrError;425426 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>427 where428 T: ?Sized + Serialize,429 {430 SerializeMap::serialize_entry(self, key, value)?;431 Ok(())432 }433434 fn end(self) -> Result<Val> {435 SerializeMap::end(self)436 }437}438439struct IntoValSerializer;440impl Serializer for IntoValSerializer {441 type Ok = Val;442443 type Error = JrError;444445 type SerializeSeq = IntoVecValSerializer;446447 type SerializeTuple = IntoVecValSerializer;448449 type SerializeTupleStruct = IntoVecValSerializer;450451 type SerializeTupleVariant = IntoVecValSerializer;452453 type SerializeMap = IntoObjValueSerializer;454455 type SerializeStruct = IntoObjValueSerializer;456457 type SerializeStructVariant = IntoObjValueSerializer;458459 fn serialize_bool(self, v: bool) -> Result<Val> {460 Ok(Val::Bool(v))461 }462463 fn serialize_i8(self, v: i8) -> Result<Val> {464 Ok(Val::Num(v.into()))465 }466467 fn serialize_i16(self, v: i16) -> Result<Val> {468 Ok(Val::Num(v.into()))469 }470471 fn serialize_i32(self, v: i32) -> Result<Val> {472 Ok(Val::Num(v.into()))473 }474475 fn serialize_i64(self, v: i64) -> Result<Val> {476 Ok(Val::Str(v.to_string().into()))477 }478479 fn serialize_u8(self, v: u8) -> Result<Val> {480 Ok(Val::Num(v.into()))481 }482483 fn serialize_u16(self, v: u16) -> Result<Val> {484 Ok(Val::Num(v.into()))485 }486487 fn serialize_u32(self, v: u32) -> Result<Val> {488 Ok(Val::Num(v.into()))489 }490491 fn serialize_u64(self, v: u64) -> Result<Val> {492 Ok(Val::Str(v.to_string().into()))493 }494495 fn serialize_f32(self, v: f32) -> Result<Val> {496 Ok(Val::try_num(f64::from(v))?)497 }498499 fn serialize_f64(self, v: f64) -> Result<Val> {500 Ok(Val::try_num(v)?)501 }502503 fn serialize_char(self, v: char) -> Result<Val> {504 Ok(Val::Str(v.to_string().into()))505 }506507 fn serialize_str(self, v: &str) -> Result<Val> {508 Ok(Val::Str(v.into()))509 }510511 fn serialize_bytes(self, v: &[u8]) -> Result<Val> {512 Ok(Val::Arr(ArrValue::bytes(v.into())))513 }514515 fn serialize_none(self) -> Result<Val> {516 Ok(Val::Null)517 }518519 fn serialize_some<T>(self, value: &T) -> Result<Val>520 where521 T: ?Sized + Serialize,522 {523 value.serialize(self)524 }525526 fn serialize_unit(self) -> Result<Val> {527 Ok(Val::Null)528 }529530 fn serialize_unit_struct(self, _name: &'static str) -> Result<Val> {531 Ok(Val::Null)532 }533534 fn serialize_unit_variant(535 self,536 _name: &'static str,537 _variant_index: u32,538 variant: &'static str,539 ) -> Result<Val> {540 Ok(Val::Str(variant.into()))541 }542543 fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<Val>544 where545 T: ?Sized + Serialize,546 {547 value.serialize(self)548 }549550 fn serialize_newtype_variant<T>(551 self,552 _name: &'static str,553 _variant_index: u32,554 variant: &'static str,555 value: &T,556 ) -> Result<Val>557 where558 T: ?Sized + Serialize,559 {560 let mut out = ObjValue::builder_with_capacity(1);561 let value = value.serialize(self)?;562 out.field(variant).value(value);563 Ok(Val::Obj(out.build()))564 }565566 fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {567 Ok(len.map_or_else(568 IntoVecValSerializer::new,569 IntoVecValSerializer::with_capacity,570 ))571 }572573 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {574 Ok(IntoVecValSerializer::with_capacity(len))575 }576577 fn serialize_tuple_struct(578 self,579 _name: &'static str,580 len: usize,581 ) -> Result<Self::SerializeTupleStruct, Self::Error> {582 Ok(IntoVecValSerializer::with_capacity(len))583 }584585 fn serialize_tuple_variant(586 self,587 _name: &'static str,588 _variant_index: u32,589 variant: &'static str,590 len: usize,591 ) -> Result<Self::SerializeTupleVariant, Self::Error> {592 Ok(IntoVecValSerializer::variant_with_capacity(variant, len))593 }594595 fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {596 Ok(len.map_or_else(597 IntoObjValueSerializer::new,598 IntoObjValueSerializer::with_capacity,599 ))600 }601602 fn serialize_struct(603 self,604 _name: &'static str,605 len: usize,606 ) -> Result<Self::SerializeStruct, Self::Error> {607 Ok(IntoObjValueSerializer::with_capacity(len))608 }609610 fn serialize_struct_variant(611 self,612 _name: &'static str,613 _variant_index: u32,614 variant: &'static str,615 len: usize,616 ) -> Result<Self::SerializeStructVariant, Self::Error> {617 Ok(IntoObjValueSerializer::variant_with_capacity(variant, len))618 }619}620621impl Val {622 pub fn from_serde(v: impl Serialize) -> Result<Self, JrError> {623 v.serialize(IntoValSerializer)624 }625}626627impl serde::ser::Error for JrError {628 fn custom<T>(msg: T) -> Self629 where630 T: std::fmt::Display,631 {632 runtime_error!("serde: {msg}")633 }634}crates/jrsonnet-evaluator/src/obj/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/obj/mod.rs
+++ b/crates/jrsonnet-evaluator/src/obj/mod.rs
@@ -792,6 +792,8 @@
key,
})
}
+
+ #[allow(dead_code, reason = "used in object ...rest destructuring")]
pub(crate) fn as_standalone(&self) -> StandaloneSuperCore {
StandaloneSuperCore {
sup: CoreIdx {
crates/jrsonnet-evaluator/src/stdlib/format.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/stdlib/format.rs
+++ b/crates/jrsonnet-evaluator/src/stdlib/format.rs
@@ -1,5 +1,10 @@
//! faster std.format impl
#![allow(clippy::too_many_arguments)]
+#![expect(
+ clippy::cast_possible_truncation,
+ clippy::cast_sign_loss,
+ reason = "many safe integer casts, behavior on overflow is not specified"
+)]
use jrsonnet_gcmodule::Trace;
use jrsonnet_interner::IStr;
crates/jrsonnet-evaluator/src/trace/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/trace/mod.rs
+++ b/crates/jrsonnet-evaluator/src/trace/mod.rs
@@ -129,6 +129,7 @@
} else {
false
};
+ #[expect(clippy::cast_possible_truncation, reason = "code is limited by 4gb")]
let mut location = path
.map_source_locations(&[offset as u32])
.into_iter()
crates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/typed/conversions.rs
+++ b/crates/jrsonnet-evaluator/src/typed/conversions.rs
@@ -157,7 +157,9 @@
}
}
+#[expect(clippy::cast_precision_loss, reason = "checked to not overflow")]
pub const MAX_SAFE_INTEGER: f64 = ((1u64 << (f64::MANTISSA_DIGITS)) - 1) as f64;
+#[expect(clippy::cast_precision_loss, reason = "checked to not overflow")]
pub const MIN_SAFE_INTEGER: f64 = (-((1i64 << (f64::MANTISSA_DIGITS)) - 1)) as f64;
macro_rules! impl_int {
@@ -179,6 +181,7 @@
stringify!($ty)
)
}
+ #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation, reason = "checked by TYPE")]
Ok(n as Self)
}
_ => unreachable!(),
@@ -198,6 +201,7 @@
macro_rules! impl_bounded_int {
($($name:ident = $ty:ty)*) => {$(
#[derive(Clone, Copy)]
+ #[allow(clippy::cast_possible_truncation, reason = "overflow is api misuse")]
pub struct $name<const MIN: $ty, const MAX: $ty>($ty);
impl<const MIN: $ty, const MAX: $ty> $name<MIN, MAX> {
pub const fn new(value: $ty) -> Option<$name<MIN, MAX>> {
@@ -219,6 +223,7 @@
}
impl<const MIN: $ty, const MAX: $ty> Typed for $name<MIN, MAX> {
+ #[allow(clippy::cast_possible_truncation, clippy::cast_precision_loss, reason = "overflow is api misuse")]
const TYPE: &'static ComplexValType =
&ComplexValType::BoundedNumber(
Some(MIN as f64),
@@ -239,6 +244,7 @@
stringify!($ty)
)
}
+ #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss, reason = "overflow is api misuse, the range is checked by TYPE")]
Ok(Self(n as $ty))
}
_ => unreachable!(),
@@ -318,6 +324,11 @@
if n.trunc() != n {
bail!("cannot convert number with fractional part to usize")
}
+ #[allow(
+ clippy::cast_possible_truncation,
+ clippy::cast_sign_loss,
+ reason = "the range is checked by TYPE"
+ )]
Ok(n as Self)
}
_ => unreachable!(),
crates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/val.rs
+++ b/crates/jrsonnet-evaluator/src/val.rs
@@ -295,8 +295,10 @@
};
let mut get_idx = |pos: Option<i32>, default| {
match pos {
- Some(v) if v < 0 => get_len().saturating_sub((-v) as usize),
+ #[expect(clippy::cast_sign_loss, reason = "abs value is used")]
+ Some(v) if v < 0 => get_len().saturating_sub((-v as isize) as usize),
// No need to clamp, as iterator interface is used
+ #[expect(clippy::cast_sign_loss, reason = "abs value is used")]
Some(v) => v as usize,
None => default,
}
@@ -322,6 +324,10 @@
Self::Arr(arr) => Ok(Self::Arr(arr.clone().slice(
index,
end,
+ #[expect(
+ clippy::cast_possible_truncation,
+ reason = "overflow will result with skip too large which would be equivalent"
+ )]
step.map(|v| NonZeroU32::new(v.value() as u32).expect("bounded != 0")),
))),
}
@@ -446,6 +452,7 @@
if self.0 < MIN_SAFE_INTEGER || self.0 > MAX_SAFE_INTEGER {
bail!("numberic value outside of safe integer range for bitwise operation");
}
+ #[expect(clippy::cast_possible_truncation, reason = "intended")]
Ok(self.0 as i64)
}
}
@@ -520,6 +527,7 @@
type Error = ConvertNumValueError;
#[inline]
fn try_from(value: $ty) -> Result<Self, ConvertNumValueError> {
+ #[expect(clippy::cast_precision_loss, reason = "precision loss is explicitly handled")]
let value = value as f64;
if value < MIN_SAFE_INTEGER {
return Err(ConvertNumValueError::Underflow)
crates/jrsonnet-interner/src/inner.rsdiffbeforeafterboth--- a/crates/jrsonnet-interner/src/inner.rs
+++ b/crates/jrsonnet-interner/src/inner.rs
@@ -67,7 +67,7 @@
.cast();
assert!(!data.is_null());
*data = InnerHeader::new(bytes.len().try_into().expect("bytes > 4GB"), is_utf8);
- ptr::copy_nonoverlapping(bytes.as_ptr(), data.offset(1).cast::<u8>(), bytes.len());
+ ptr::copy_nonoverlapping(bytes.as_ptr(), data.add(1).cast::<u8>(), bytes.len());
Self(UnsafeCell::new(NonNull::new_unchecked(data)))
}
}
@@ -89,10 +89,7 @@
let size = unsafe { (*header).size };
// SAFETY: bytes after data is allocated to be exactly data.size in length
unsafe {
- slice::from_raw_parts(
- (*self.0.get()).as_ptr().offset(1).cast::<u8>(),
- size as usize,
- )
+ slice::from_raw_parts((*self.0.get()).as_ptr().add(1).cast::<u8>(), size as usize)
}
}
@@ -156,7 +153,7 @@
}
pub fn as_ptr(this: &Self) -> *const u8 {
// SAFETY: data is initialized
- unsafe { (*this.0.get()).as_ptr().offset(1).cast() }
+ unsafe { (*this.0.get()).as_ptr().add(1).cast() }
}
pub fn strong_count(this: &Self) -> u32 {
crates/jrsonnet-ir-parser/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-ir-parser/src/lib.rs
+++ b/crates/jrsonnet-ir-parser/src/lib.rs
@@ -638,6 +638,7 @@
}
}
+#[allow(clippy::too_many_lines)]
fn expr_basic(p: &mut Parser<'_>) -> Result<Expr> {
if let Some(lit) = literal(p) {
return Ok(Expr::Literal(lit));
@@ -764,7 +765,6 @@
}
SyntaxKind::IDENT => {
- let text = p.text();
let n = spanned(p, |p| {
let s: IStr = p.text().into();
p.eat_any();
@@ -1005,8 +1005,9 @@
}
pub fn string_to_expr(s: IStr, settings: &ParserSettings) -> Spanned<Expr> {
- let len = s.len();
- Spanned::new(Expr::Str(s), Span(settings.source.clone(), 0, len as u32))
+ let len = u32::try_from(s.len()).expect("code size is limited by 4gb");
+
+ Spanned::new(Expr::Str(s), Span(settings.source.clone(), 0, len))
}
#[cfg(test)]
crates/jrsonnet-lexer/src/lex.rsdiffbeforeafterboth--- a/crates/jrsonnet-lexer/src/lex.rs
+++ b/crates/jrsonnet-lexer/src/lex.rs
@@ -60,7 +60,10 @@
range: {
let Range { start, end } = self.inner.span();
- Span(start as u32, end as u32)
+ Span(
+ u32::try_from(start).expect("code size is limited by 4gb"),
+ u32::try_from(end).expect("code size is limited by 4gb"),
+ )
},
})
}
crates/jrsonnet-stdlib/src/arrays.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/arrays.rs
+++ b/crates/jrsonnet-stdlib/src/arrays.rs
@@ -17,7 +17,11 @@
}
#[builtin]
-pub fn builtin_make_array(sz: BoundedI32<0, { i32::MAX }>, func: FuncVal) -> Result<ArrValue> {
+pub fn builtin_make_array(
+ // Can't use usize because range_exclusive is over i32
+ sz: BoundedI32<0, { i32::MAX }>,
+ func: FuncVal,
+) -> Result<ArrValue> {
if *sz == 0 {
return Ok(ArrValue::empty());
}
@@ -25,6 +29,7 @@
// TODO: Different mapped array impl avoiding allocating unnecessary vals
|| Ok(ArrValue::range_exclusive(0, *sz).map(FromUntyped::from_untyped(Val::Func(func))?)),
|trivial| {
+ #[expect(clippy::cast_sign_loss, reason = "sz is bounded to be larger than 0")]
let mut out = Vec::with_capacity(*sz as usize);
for _ in 0..*sz {
out.push(trivial.clone());
@@ -363,6 +368,10 @@
if arr.is_empty() {
return eval_on_empty(onEmpty);
}
+ #[expect(
+ clippy::cast_precision_loss,
+ reason = "array sizes are bounded to i32 len"
+ )]
Ok(Val::try_num(arr.iter().sum::<f64>() / (arr.len() as f64))?)
}
@@ -378,6 +387,11 @@
pub fn builtin_remove(arr: ArrValue, elem: Val) -> Result<ArrValue> {
for (index, item) in arr.iter().enumerate() {
if equals(&item?, &elem)? {
+ #[expect(
+ clippy::cast_possible_truncation,
+ clippy::cast_possible_wrap,
+ reason = "array sizes are bounded to i32 len"
+ )]
return builtin_remove_at(arr.clone(), index as i32);
}
}
crates/jrsonnet-stdlib/src/math.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/math.rs
+++ b/crates/jrsonnet-stdlib/src/math.rs
@@ -120,6 +120,7 @@
let lg = s.abs().log2();
let x = (lg - lg.floor() - 1.0).exp2();
let exp = lg.floor() + 1.0;
+ #[expect(clippy::cast_possible_truncation, reason = "exponent can fit in i16")]
(s.signum() * x, exp as i16)
}
}
flake.nixdiffbeforeafterboth--- a/flake.nix
+++ b/flake.nix
@@ -66,6 +66,7 @@
"clippy"
"rustc"
"rust-src"
+ "rust-analyzer"
])
rustfmt
];