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
--- 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"
modifiedcrates/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(),
 		})
modifiedcrates/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),
 		}
 	}
modifiedcrates/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)
 					}),
modifiedcrates/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)?
 		}
 
modifiedcrates/jrsonnet-evaluator/src/integrations/serde.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/integrations/serde.rs
+++ b/crates/jrsonnet-evaluator/src/integrations/serde.rs
@@ -69,12 +69,20 @@
 			where
 				E: de::Error,
 			{
+				#[expect(
+					clippy::cast_precision_loss,
+					reason = "this is how it works with stdlib functions"
+				)]
 				Ok(Val::Num(NumValue::new(v as f64).expect("no overflow")))
 			}
 			fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
 			where
 				E: de::Error,
 			{
+				#[expect(
+					clippy::cast_precision_loss,
+					reason = "this is how it works with stdlib functions"
+				)]
 				Ok(Val::Num(NumValue::new(v as f64).expect("no overflow")))
 			}
 
@@ -161,6 +169,10 @@
 			Self::Num(n) => {
 				let n = n.get();
 				if n.fract() == 0.0 {
+					#[expect(
+						clippy::cast_possible_truncation,
+						reason = "no correct implementation is possible here; expected"
+					)]
 					let n = n as i64;
 					serializer.serialize_i64(n)
 				} else {
modifiedcrates/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 {
modifiedcrates/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;
modifiedcrates/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()
modifiedcrates/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!(),
modifiedcrates/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)
modifiedcrates/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 {
modifiedcrates/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)]
modifiedcrates/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"),
+				)
 			},
 		})
 	}
modifiedcrates/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);
 		}
 	}
modifiedcrates/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)
 	}
 }
modifiedflake.nixdiffbeforeafterboth
before · flake.nix
1{2  description = "Jrsonnet";3  inputs = {4    nixpkgs.url = "github:nixos/nixpkgs/release-25.11";5    fenix = {6      url = "github:CertainLach/fenix/fix/libatomic";7      inputs.nixpkgs.follows = "nixpkgs";8    };9    flake-parts = {10      url = "github:hercules-ci/flake-parts";11      inputs.nixpkgs-lib.follows = "nixpkgs";12    };13    hercules-ci-effects = {14      url = "github:hercules-ci/hercules-ci-effects";15      inputs.flake-parts.follows = "flake-parts";16      inputs.nixpkgs.follows = "nixpkgs";17    };18    treefmt-nix = {19      url = "github:numtide/treefmt-nix";20      inputs.nixpkgs.follows = "nixpkgs";21    };22    crane.url = "github:CertainLach/crane/refactor/drop-remarshal";23    shelly.url = "github:CertainLach/shelly";24  };25  outputs =26    inputs:27    let28      inherit (inputs.nixpkgs.lib)29        mkIf30        mkForce31        optionals32        optionalAttrs33        ;34    in35    inputs.flake-parts.lib.mkFlake { inherit inputs; } {36      imports = [37        inputs.shelly.flakeModule38        inputs.hercules-ci-effects.flakeModule39      ];40      systems = [41        "x86_64-linux"42        "i686-linux"43        "aarch64-linux"44        "armv7l-linux"45        "aarch64-darwin"46      ];47      perSystem =48        {49          config,50          self',51          system,52          ...53        }:54        let55          pkgs = import inputs.nixpkgs {56            inherit system;57            overlays = [ inputs.fenix.overlays.default ];58            config.allowUnsupportedSystem = true;59            config.allowUnfreePredicate = pkg: pkg.name == "Xcode.app";60          };61          targetArch = pkgs.stdenv.hostPlatform.parsed.cpu.name;62          rustfmt = (pkgs.fenix.complete or pkgs.fenix.stable).rustfmt;63          toolchain = pkgs.fenix.combine [64            (pkgs.fenix.stable.withComponents [65              "cargo"66              "clippy"67              "rustc"68              "rust-src"69            ])70            rustfmt71          ];72          craneLib = (inputs.crane.mkLib pkgs).overrideToolchain toolchain;73          treefmt =74            (inputs.treefmt-nix.lib.evalModule pkgs (import ./treefmt.nix { inherit rustfmt; })).config.build;7576          # Cross-compilation toolchains77          crossToolchain = pkgs.fenix.combine [78            (pkgs.fenix.stable.withComponents [79              "cargo"80              "rustc"81            ])82            pkgs.fenix.targets."${targetArch}-unknown-linux-musl".stable.rust-std83            pkgs.fenix.targets."${targetArch}-apple-darwin".stable.rust-std84          ];85          craneLibCross = (inputs.crane.mkLib pkgs).overrideToolchain crossToolchain;8687          # Windows cross-compilation88          pkgsWindows = import inputs.nixpkgs {89            overlays = [ inputs.fenix.overlays.default ];90            localSystem = system;91            crossSystem = {92              config = "${targetArch}-w64-mingw32";93              libc = "msvcrt";94            };95          };96          windowsToolchain = pkgs.fenix.combine [97            (pkgs.fenix.stable.withComponents [98              "cargo"99              "rustc"100            ])101            pkgs.fenix.targets."${targetArch}-pc-windows-gnu".stable.rust-std102          ];103          craneLibWindows = (inputs.crane.mkLib pkgsWindows).overrideToolchain (_: windowsToolchain);104105        in106        {107          legacyPackages = {108            release = optionalAttrs pkgs.stdenv.hostPlatform.isLinux (109              {110                jrsonnet-linux-glibc = self'.packages.jrsonnet;111                jrsonnet-experimental-linux-glibc = self'.packages.jrsonnet-experimental;112              }113              // optionalAttrs pkgs.stdenv.hostPlatform.is64bit rec {114                jrsonnet-linux-musl = pkgs.callPackage ./nix/jrsonnet-cross-musl.nix {115                  craneLib = craneLibCross;116                  targetTriple = "${targetArch}-unknown-linux-musl";117                  muslCC = pkgs.pkgsMusl.stdenv.cc;118                };119                jrsonnet-experimental-linux-musl = jrsonnet-linux-musl.override {120                  withExperimentalFeatures = true;121                };122              }123              // optionalAttrs (targetArch == "aarch64") rec {124                jrsonnet-darwin = pkgs.callPackage ./nix/jrsonnet-cross-darwin.nix {125                  craneLib = craneLibCross;126                  targetTriple = "${targetArch}-apple-darwin";127                };128                jrsonnet-experimental-darwin = jrsonnet-darwin.override {129                  withExperimentalFeatures = true;130                };131              }132              // optionalAttrs (targetArch == "x86_64") rec {133                jrsonnet-windows = pkgsWindows.callPackage ./nix/jrsonnet-cross-windows.nix {134                  craneLib = craneLibWindows;135                  targetTriple = "${targetArch}-pc-windows-gnu";136                };137                jrsonnet-experimental-windows = jrsonnet-windows.override {138                  withExperimentalFeatures = true;139                };140              }141            );142            benchmarks = optionalAttrs (system == "x86_64-linux" || system == "aarch64-linux") {143              default = pkgs.callPackage ./nix/benchmarks.nix {144                inherit (config.legacyPackages.jsonnetImpls)145                  go-jsonnet146                  sjsonnet147                  cpp-jsonnet148                  rsjsonnet149                  ;150                jrsonnetVariants = [151                  {152                    drv = self'.packages.jrsonnet.override { forBenchmarks = true; };153                    name = "";154                  }155                ];156              };157              quick = pkgs.callPackage ./nix/benchmarks.nix {158                inherit (config.legacyPackages.jsonnetImpls)159                  go-jsonnet160                  sjsonnet161                  cpp-jsonnet162                  rsjsonnet163                  ;164                quick = true;165                jrsonnetVariants = [166                  {167                    drv = self'.packages.jrsonnet.override { forBenchmarks = true; };168                    name = "";169                  }170                ];171              };172              against-release = pkgs.callPackage ./nix/benchmarks.nix {173                inherit (config.legacyPackages.jsonnetImpls)174                  go-jsonnet175                  sjsonnet176                  cpp-jsonnet177                  rsjsonnet178                  ;179                jrsonnetVariants = [180                  {181                    drv = self'.packages.jrsonnet.override { forBenchmarks = true; };182                    name = "current";183                  }184                  {185                    drv = self'.packages.jrsonnet-experimental.override { forBenchmarks = true; };186                    name = "current-experimental";187                  }188                  {189                    drv = self'.legacyPackages.jsonnetImpls.jrsonnet-release.override { forBenchmarks = true; };190                    name = "release";191                  }192                ];193              };194              quick-against-release = pkgs.callPackage ./nix/benchmarks.nix {195                inherit (config.legacyPackages.jsonnetImpls)196                  go-jsonnet197                  sjsonnet198                  cpp-jsonnet199                  rsjsonnet200                  ;201                quick = true;202                jrsonnetVariants = [203                  {204                    drv = self'.packages.jrsonnet.override { forBenchmarks = true; };205                    name = "current";206                  }207                  {208                    drv = self'.packages.jrsonnet-experimental.override { forBenchmarks = true; };209                    name = "current-experimental";210                  }211                  {212                    drv = self'.legacyPackages.jsonnetImpls.jrsonnet-release.override { forBenchmarks = true; };213                    name = "release";214                  }215                ];216              };217            };218            jsonnetImpls = {219              go-jsonnet = pkgs.callPackage ./nix/go-jsonnet.nix { };220              sjsonnet = pkgs.callPackage ./nix/sjsonnet.nix { };221              cpp-jsonnet = pkgs.callPackage ./nix/cpp-jsonnet.nix { };222              # I didn't managed to build it, and nixpkgs version is marked as broken223              # haskell-jsonnet = pkgs.callPackage ./nix/haskell-jsonnet.nix { };224              rsjsonnet = pkgs.callPackage ./nix/rsjsonnet.nix { };225              # Older released version of jrsonnet itself, for benchmarking purposes226              jrsonnet-release = pkgs.callPackage ./nix/jrsonnet-release.nix {227                rustPlatform = pkgs.makeRustPlatform {228                  rustc = toolchain;229                  cargo = toolchain;230                };231              };232            };233          };234          packages =235            let236              jrsonnet = pkgs.callPackage ./nix/jrsonnet.nix {237                inherit craneLib;238              };239              jrsonnet-experimental = pkgs.callPackage ./nix/jrsonnet.nix {240                inherit craneLib;241                withExperimentalFeatures = true;242              };243            in244            {245              default = jrsonnet;246              inherit jrsonnet jrsonnet-experimental;247            };248          checks = optionalAttrs (system != "armv7l-linux") {249            formatting = treefmt.check inputs.self;250          };251          formatter = mkIf (system != "armv7l-linux") treefmt.wrapper;252          shelly.shells.default = {253            factory = craneLib.devShell;254            packages =255              with pkgs;256              [257                cargo-edit258                cargo-outdated259                cargo-watch260                cargo-insta261                cargo-hack262                cargo-show-asm263                lld264                hyperfine265                graphviz266              ]267              ++ optionals (!stdenv.isDarwin) [268                valgrind269                kdePackages.kcachegrind270                samply271              ];272          };273        };274      hercules-ci.github-releases.files =275        let276          rel = system: inputs.self.legacyPackages.${system}.release;277          bin = drv: "${drv}/bin/jrsonnet";278          exe = drv: "${drv}/bin/jrsonnet.exe";279        in280        [281          {282            label = "jrsonnet-x86_64-linux-musl";283            path = bin (rel "x86_64-linux").jrsonnet-linux-musl;284          }285          {286            label = "jrsonnet-experimental-x86_64-linux-musl";287            path = bin (rel "x86_64-linux").jrsonnet-experimental-linux-musl;288          }289          {290            label = "jrsonnet-aarch64-darwin";291            path = bin (rel "aarch64-linux").jrsonnet-darwin;292          }293          {294            label = "jrsonnet-experimental-aarch64-darwin";295            path = bin (rel "aarch64-linux").jrsonnet-experimental-darwin;296          }297          {298            label = "jrsonnet-x86_64-windows.exe";299            path = exe (rel "x86_64-linux").jrsonnet-windows;300          }301          {302            label = "jrsonnet-experimental-x86_64-windows.exe";303            path = exe (rel "x86_64-linux").jrsonnet-experimental-windows;304          }305306          {307            label = "jrsonnet-aarch64-linux-musl";308            path = bin (rel "aarch64-linux").jrsonnet-linux-musl;309          }310          {311            label = "jrsonnet-experimental-aarch64-linux-musl";312            path = bin (rel "aarch64-linux").jrsonnet-experimental-linux-musl;313          }314315          {316            label = "jrsonnet-x86_64-linux-glibc";317            path = bin (rel "x86_64-linux").jrsonnet-linux-glibc;318          }319          {320            label = "jrsonnet-experimental-x86_64-linux-glibc";321            path = bin (rel "x86_64-linux").jrsonnet-experimental-linux-glibc;322          }323          {324            label = "jrsonnet-aarch64-linux-glibc";325            path = bin (rel "aarch64-linux").jrsonnet-linux-glibc;326          }327          {328            label = "jrsonnet-experimental-aarch64-linux-glibc";329            path = bin (rel "aarch64-linux").jrsonnet-experimental-linux-glibc;330          }331          {332            label = "jrsonnet-i686-linux-glibc";333            path = bin (rel "i686-linux").jrsonnet-linux-glibc;334          }335          {336            label = "jrsonnet-experimental-i686-linux-glibc";337            path = bin (rel "i686-linux").jrsonnet-experimental-linux-glibc;338          }339          {340            label = "jrsonnet-armv7l-linux-glibc";341            path = bin (rel "armv7l-linux").jrsonnet-linux-glibc;342          }343          {344            label = "jrsonnet-experimental-armv7l-linux-glibc";345            path = bin (rel "armv7l-linux").jrsonnet-experimental-linux-glibc;346          }347        ];348      hercules-ci.cargo-publish = {349        enable = true;350        secretName = "crates-io";351      };352      hercules-ci.flake-update = {353        enable = true;354        baseMerge.enable = true;355        baseMerge.method = "fast-forward";356        when = {357          dayOfWeek = [ "Sat" ];358        };359      };360      herculesCI =361        { lib, config, ... }:362        {363          ciSystems = [364            "x86_64-linux"365            "i686-linux"366            "aarch64-linux"367            "armv7l-linux"368            # TODO: add workers for these platforms369            # "aarch64-darwin"370          ];371          onPush.default.outputs = {372            benchmarks.x86_64-linux = inputs.self.legacyPackages.x86_64-linux.benchmarks.default;373374            # Cross: musl/mingw/darwin-zigbuild375            release.x86_64-linux = inputs.self.legacyPackages.x86_64-linux.release;376            release.aarch64-linux = inputs.self.legacyPackages.aarch64-linux.release;377            release.armv7l-linux = inputs.self.legacyPackages.armv7l-linux.release;378            release.i686-linux = inputs.self.legacyPackages.i686-linux.release;379380            # Too much to build for CI purposes381            devShells = mkForce { };382            formatter = mkForce { };383384            # No need to run them on different arch, pretty large derivations and might try to compile GHC385            checks.i686-linux.formatting = mkForce { };386            checks.aarch64-linux.formatting = mkForce { };387          };388        };389    };390}
after · flake.nix
1{2  description = "Jrsonnet";3  inputs = {4    nixpkgs.url = "github:nixos/nixpkgs/release-25.11";5    fenix = {6      url = "github:CertainLach/fenix/fix/libatomic";7      inputs.nixpkgs.follows = "nixpkgs";8    };9    flake-parts = {10      url = "github:hercules-ci/flake-parts";11      inputs.nixpkgs-lib.follows = "nixpkgs";12    };13    hercules-ci-effects = {14      url = "github:hercules-ci/hercules-ci-effects";15      inputs.flake-parts.follows = "flake-parts";16      inputs.nixpkgs.follows = "nixpkgs";17    };18    treefmt-nix = {19      url = "github:numtide/treefmt-nix";20      inputs.nixpkgs.follows = "nixpkgs";21    };22    crane.url = "github:CertainLach/crane/refactor/drop-remarshal";23    shelly.url = "github:CertainLach/shelly";24  };25  outputs =26    inputs:27    let28      inherit (inputs.nixpkgs.lib)29        mkIf30        mkForce31        optionals32        optionalAttrs33        ;34    in35    inputs.flake-parts.lib.mkFlake { inherit inputs; } {36      imports = [37        inputs.shelly.flakeModule38        inputs.hercules-ci-effects.flakeModule39      ];40      systems = [41        "x86_64-linux"42        "i686-linux"43        "aarch64-linux"44        "armv7l-linux"45        "aarch64-darwin"46      ];47      perSystem =48        {49          config,50          self',51          system,52          ...53        }:54        let55          pkgs = import inputs.nixpkgs {56            inherit system;57            overlays = [ inputs.fenix.overlays.default ];58            config.allowUnsupportedSystem = true;59            config.allowUnfreePredicate = pkg: pkg.name == "Xcode.app";60          };61          targetArch = pkgs.stdenv.hostPlatform.parsed.cpu.name;62          rustfmt = (pkgs.fenix.complete or pkgs.fenix.stable).rustfmt;63          toolchain = pkgs.fenix.combine [64            (pkgs.fenix.stable.withComponents [65              "cargo"66              "clippy"67              "rustc"68              "rust-src"69              "rust-analyzer"70            ])71            rustfmt72          ];73          craneLib = (inputs.crane.mkLib pkgs).overrideToolchain toolchain;74          treefmt =75            (inputs.treefmt-nix.lib.evalModule pkgs (import ./treefmt.nix { inherit rustfmt; })).config.build;7677          # Cross-compilation toolchains78          crossToolchain = pkgs.fenix.combine [79            (pkgs.fenix.stable.withComponents [80              "cargo"81              "rustc"82            ])83            pkgs.fenix.targets."${targetArch}-unknown-linux-musl".stable.rust-std84            pkgs.fenix.targets."${targetArch}-apple-darwin".stable.rust-std85          ];86          craneLibCross = (inputs.crane.mkLib pkgs).overrideToolchain crossToolchain;8788          # Windows cross-compilation89          pkgsWindows = import inputs.nixpkgs {90            overlays = [ inputs.fenix.overlays.default ];91            localSystem = system;92            crossSystem = {93              config = "${targetArch}-w64-mingw32";94              libc = "msvcrt";95            };96          };97          windowsToolchain = pkgs.fenix.combine [98            (pkgs.fenix.stable.withComponents [99              "cargo"100              "rustc"101            ])102            pkgs.fenix.targets."${targetArch}-pc-windows-gnu".stable.rust-std103          ];104          craneLibWindows = (inputs.crane.mkLib pkgsWindows).overrideToolchain (_: windowsToolchain);105106        in107        {108          legacyPackages = {109            release = optionalAttrs pkgs.stdenv.hostPlatform.isLinux (110              {111                jrsonnet-linux-glibc = self'.packages.jrsonnet;112                jrsonnet-experimental-linux-glibc = self'.packages.jrsonnet-experimental;113              }114              // optionalAttrs pkgs.stdenv.hostPlatform.is64bit rec {115                jrsonnet-linux-musl = pkgs.callPackage ./nix/jrsonnet-cross-musl.nix {116                  craneLib = craneLibCross;117                  targetTriple = "${targetArch}-unknown-linux-musl";118                  muslCC = pkgs.pkgsMusl.stdenv.cc;119                };120                jrsonnet-experimental-linux-musl = jrsonnet-linux-musl.override {121                  withExperimentalFeatures = true;122                };123              }124              // optionalAttrs (targetArch == "aarch64") rec {125                jrsonnet-darwin = pkgs.callPackage ./nix/jrsonnet-cross-darwin.nix {126                  craneLib = craneLibCross;127                  targetTriple = "${targetArch}-apple-darwin";128                };129                jrsonnet-experimental-darwin = jrsonnet-darwin.override {130                  withExperimentalFeatures = true;131                };132              }133              // optionalAttrs (targetArch == "x86_64") rec {134                jrsonnet-windows = pkgsWindows.callPackage ./nix/jrsonnet-cross-windows.nix {135                  craneLib = craneLibWindows;136                  targetTriple = "${targetArch}-pc-windows-gnu";137                };138                jrsonnet-experimental-windows = jrsonnet-windows.override {139                  withExperimentalFeatures = true;140                };141              }142            );143            benchmarks = optionalAttrs (system == "x86_64-linux" || system == "aarch64-linux") {144              default = pkgs.callPackage ./nix/benchmarks.nix {145                inherit (config.legacyPackages.jsonnetImpls)146                  go-jsonnet147                  sjsonnet148                  cpp-jsonnet149                  rsjsonnet150                  ;151                jrsonnetVariants = [152                  {153                    drv = self'.packages.jrsonnet.override { forBenchmarks = true; };154                    name = "";155                  }156                ];157              };158              quick = pkgs.callPackage ./nix/benchmarks.nix {159                inherit (config.legacyPackages.jsonnetImpls)160                  go-jsonnet161                  sjsonnet162                  cpp-jsonnet163                  rsjsonnet164                  ;165                quick = true;166                jrsonnetVariants = [167                  {168                    drv = self'.packages.jrsonnet.override { forBenchmarks = true; };169                    name = "";170                  }171                ];172              };173              against-release = pkgs.callPackage ./nix/benchmarks.nix {174                inherit (config.legacyPackages.jsonnetImpls)175                  go-jsonnet176                  sjsonnet177                  cpp-jsonnet178                  rsjsonnet179                  ;180                jrsonnetVariants = [181                  {182                    drv = self'.packages.jrsonnet.override { forBenchmarks = true; };183                    name = "current";184                  }185                  {186                    drv = self'.packages.jrsonnet-experimental.override { forBenchmarks = true; };187                    name = "current-experimental";188                  }189                  {190                    drv = self'.legacyPackages.jsonnetImpls.jrsonnet-release.override { forBenchmarks = true; };191                    name = "release";192                  }193                ];194              };195              quick-against-release = pkgs.callPackage ./nix/benchmarks.nix {196                inherit (config.legacyPackages.jsonnetImpls)197                  go-jsonnet198                  sjsonnet199                  cpp-jsonnet200                  rsjsonnet201                  ;202                quick = true;203                jrsonnetVariants = [204                  {205                    drv = self'.packages.jrsonnet.override { forBenchmarks = true; };206                    name = "current";207                  }208                  {209                    drv = self'.packages.jrsonnet-experimental.override { forBenchmarks = true; };210                    name = "current-experimental";211                  }212                  {213                    drv = self'.legacyPackages.jsonnetImpls.jrsonnet-release.override { forBenchmarks = true; };214                    name = "release";215                  }216                ];217              };218            };219            jsonnetImpls = {220              go-jsonnet = pkgs.callPackage ./nix/go-jsonnet.nix { };221              sjsonnet = pkgs.callPackage ./nix/sjsonnet.nix { };222              cpp-jsonnet = pkgs.callPackage ./nix/cpp-jsonnet.nix { };223              # I didn't managed to build it, and nixpkgs version is marked as broken224              # haskell-jsonnet = pkgs.callPackage ./nix/haskell-jsonnet.nix { };225              rsjsonnet = pkgs.callPackage ./nix/rsjsonnet.nix { };226              # Older released version of jrsonnet itself, for benchmarking purposes227              jrsonnet-release = pkgs.callPackage ./nix/jrsonnet-release.nix {228                rustPlatform = pkgs.makeRustPlatform {229                  rustc = toolchain;230                  cargo = toolchain;231                };232              };233            };234          };235          packages =236            let237              jrsonnet = pkgs.callPackage ./nix/jrsonnet.nix {238                inherit craneLib;239              };240              jrsonnet-experimental = pkgs.callPackage ./nix/jrsonnet.nix {241                inherit craneLib;242                withExperimentalFeatures = true;243              };244            in245            {246              default = jrsonnet;247              inherit jrsonnet jrsonnet-experimental;248            };249          checks = optionalAttrs (system != "armv7l-linux") {250            formatting = treefmt.check inputs.self;251          };252          formatter = mkIf (system != "armv7l-linux") treefmt.wrapper;253          shelly.shells.default = {254            factory = craneLib.devShell;255            packages =256              with pkgs;257              [258                cargo-edit259                cargo-outdated260                cargo-watch261                cargo-insta262                cargo-hack263                cargo-show-asm264                lld265                hyperfine266                graphviz267              ]268              ++ optionals (!stdenv.isDarwin) [269                valgrind270                kdePackages.kcachegrind271                samply272              ];273          };274        };275      hercules-ci.github-releases.files =276        let277          rel = system: inputs.self.legacyPackages.${system}.release;278          bin = drv: "${drv}/bin/jrsonnet";279          exe = drv: "${drv}/bin/jrsonnet.exe";280        in281        [282          {283            label = "jrsonnet-x86_64-linux-musl";284            path = bin (rel "x86_64-linux").jrsonnet-linux-musl;285          }286          {287            label = "jrsonnet-experimental-x86_64-linux-musl";288            path = bin (rel "x86_64-linux").jrsonnet-experimental-linux-musl;289          }290          {291            label = "jrsonnet-aarch64-darwin";292            path = bin (rel "aarch64-linux").jrsonnet-darwin;293          }294          {295            label = "jrsonnet-experimental-aarch64-darwin";296            path = bin (rel "aarch64-linux").jrsonnet-experimental-darwin;297          }298          {299            label = "jrsonnet-x86_64-windows.exe";300            path = exe (rel "x86_64-linux").jrsonnet-windows;301          }302          {303            label = "jrsonnet-experimental-x86_64-windows.exe";304            path = exe (rel "x86_64-linux").jrsonnet-experimental-windows;305          }306307          {308            label = "jrsonnet-aarch64-linux-musl";309            path = bin (rel "aarch64-linux").jrsonnet-linux-musl;310          }311          {312            label = "jrsonnet-experimental-aarch64-linux-musl";313            path = bin (rel "aarch64-linux").jrsonnet-experimental-linux-musl;314          }315316          {317            label = "jrsonnet-x86_64-linux-glibc";318            path = bin (rel "x86_64-linux").jrsonnet-linux-glibc;319          }320          {321            label = "jrsonnet-experimental-x86_64-linux-glibc";322            path = bin (rel "x86_64-linux").jrsonnet-experimental-linux-glibc;323          }324          {325            label = "jrsonnet-aarch64-linux-glibc";326            path = bin (rel "aarch64-linux").jrsonnet-linux-glibc;327          }328          {329            label = "jrsonnet-experimental-aarch64-linux-glibc";330            path = bin (rel "aarch64-linux").jrsonnet-experimental-linux-glibc;331          }332          {333            label = "jrsonnet-i686-linux-glibc";334            path = bin (rel "i686-linux").jrsonnet-linux-glibc;335          }336          {337            label = "jrsonnet-experimental-i686-linux-glibc";338            path = bin (rel "i686-linux").jrsonnet-experimental-linux-glibc;339          }340          {341            label = "jrsonnet-armv7l-linux-glibc";342            path = bin (rel "armv7l-linux").jrsonnet-linux-glibc;343          }344          {345            label = "jrsonnet-experimental-armv7l-linux-glibc";346            path = bin (rel "armv7l-linux").jrsonnet-experimental-linux-glibc;347          }348        ];349      hercules-ci.cargo-publish = {350        enable = true;351        secretName = "crates-io";352      };353      hercules-ci.flake-update = {354        enable = true;355        baseMerge.enable = true;356        baseMerge.method = "fast-forward";357        when = {358          dayOfWeek = [ "Sat" ];359        };360      };361      herculesCI =362        { lib, config, ... }:363        {364          ciSystems = [365            "x86_64-linux"366            "i686-linux"367            "aarch64-linux"368            "armv7l-linux"369            # TODO: add workers for these platforms370            # "aarch64-darwin"371          ];372          onPush.default.outputs = {373            benchmarks.x86_64-linux = inputs.self.legacyPackages.x86_64-linux.benchmarks.default;374375            # Cross: musl/mingw/darwin-zigbuild376            release.x86_64-linux = inputs.self.legacyPackages.x86_64-linux.release;377            release.aarch64-linux = inputs.self.legacyPackages.aarch64-linux.release;378            release.armv7l-linux = inputs.self.legacyPackages.armv7l-linux.release;379            release.i686-linux = inputs.self.legacyPackages.i686-linux.release;380381            # Too much to build for CI purposes382            devShells = mkForce { };383            formatter = mkForce { };384385            # No need to run them on different arch, pretty large derivations and might try to compile GHC386            checks.i686-linux.formatting = mkForce { };387            checks.aarch64-linux.formatting = mkForce { };388          };389        };390    };391}