git.delta.rocks / jrsonnet / refs/commits / 7cd3ab4b3483

difftreelog

style fix clippy warnings

Yaroslav Bolyukin2024-08-26parent: #7cdcae3.patch.diff
in: master

19 files changed

modifiedCargo.lockdiffbeforeafterboth
before · Cargo.lock
154 packageslockfile v3
after · Cargo.lock
160 packageslockfile v3
modifiedCargo.tomldiffbeforeafterboth
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -89,6 +89,7 @@
 lru = "0.12.3"
 
 json-structural-diff = "0.1.0"
+syn-dissect-closure = "0.1.0"
 
 [workspace.lints.rust]
 unsafe_op_in_unsafe_fn = "deny"
@@ -107,9 +108,9 @@
 all = "warn"
 
 [workspace.lints.clippy]
-all = "warn"
-nursery = "warn"
-pedantic = "warn"
+all = { level = "warn", priority = -1 }
+nursery = { level = "warn", priority = -1 }
+pedantic = { level = "warn", priority = -1 }
 
 ptr_arg = "allow"
 # Too verbose
modifiedbindings/jsonnet/src/native.rsdiffbeforeafterboth
--- a/bindings/jsonnet/src/native.rs
+++ b/bindings/jsonnet/src/native.rs
@@ -20,6 +20,7 @@
 /// - `ctx` User pointer, given in `jsonnet_native_callback`.
 /// - `argv` Array of arguments from Jsonnet code.
 /// - `param` success Set this byref param to 1 to indicate success and 0 for failure.
+///
 /// Returns the content of the imported file, or an error message.
 type JsonnetNativeCallback = unsafe extern "C" fn(
 	ctx: *const c_void,
modifiedcmds/jrsonnet-fmt/src/comments.rsdiffbeforeafterboth
--- a/cmds/jrsonnet-fmt/src/comments.rs
+++ b/cmds/jrsonnet-fmt/src/comments.rs
@@ -20,7 +20,7 @@
 		let Ok(c) = c else {
 			let mut text = c.as_ref().unwrap_err() as &str;
 			while !text.is_empty() {
-				let pos = text.find(|c| c == '\n' || c == '\t').unwrap_or(text.len());
+				let pos = text.find(['\n', '\t']).unwrap_or(text.len());
 				let sliced = &text[..pos];
 				p!(out, string(sliced.to_string()));
 				text = &text[pos..];
modifiedcmds/jrsonnet-fmt/src/tests.rsdiffbeforeafterboth
--- a/cmds/jrsonnet-fmt/src/tests.rs
+++ b/cmds/jrsonnet-fmt/src/tests.rs
@@ -75,5 +75,5 @@
             b: '',
           },
         }"
-	)))
+	)));
 }
modifiedcrates/jrsonnet-evaluator/src/function/arglike.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/function/arglike.rs
+++ b/crates/jrsonnet-evaluator/src/function/arglike.rs
@@ -91,6 +91,7 @@
 		handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,
 	) -> Result<()>;
 	fn named_names(&self, handler: &mut dyn FnMut(&IStr));
+	fn is_empty(&self) -> bool;
 }
 
 impl ArgsLike for Vec<Val> {
@@ -117,6 +118,9 @@
 		Ok(())
 	}
 	fn named_names(&self, _handler: &mut dyn FnMut(&IStr)) {}
+	fn is_empty(&self) -> bool {
+		self.is_empty()
+	}
 }
 
 impl ArgsLike for ArgsDesc {
@@ -173,6 +177,10 @@
 			handler(name);
 		}
 	}
+
+	fn is_empty(&self) -> bool {
+		self.unnamed.is_empty() && self.named.is_empty()
+	}
 }
 
 impl<V: ArgLike, S> ArgsLike for HashMap<IStr, V, S> {
@@ -206,6 +214,10 @@
 			handler(name);
 		}
 	}
+
+	fn is_empty(&self) -> bool {
+		self.is_empty()
+	}
 }
 impl<V, S> OptionalContext for HashMap<IStr, V, S> where V: ArgLike + OptionalContext {}
 
@@ -235,6 +247,10 @@
 	fn named_names(&self, handler: &mut dyn FnMut(&IStr)) {
 		self.0.named_names(handler);
 	}
+
+	fn is_empty(&self) -> bool {
+		self.0.is_empty()
+	}
 }
 
 macro_rules! impl_args_like {
@@ -267,43 +283,13 @@
 				Ok(())
 			}
 			fn named_names(&self, _handler: &mut dyn FnMut(&IStr)) {}
-		}
-		impl<$($gen: ArgLike,)*> OptionalContext for ($($gen,)*) where $($gen: OptionalContext),* {}
 
-		impl<$($gen: ArgLike,)*> ArgsLike for ($((IStr, $gen),)*) {
-			fn unnamed_len(&self) -> usize {
-				0
-			}
-			fn unnamed_iter(
-				&self,
-				_ctx: Context,
-				_tailstrict: bool,
-				_handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,
-			) -> Result<()> {
-				Ok(())
-			}
-			#[allow(non_snake_case)]
-			fn named_iter(
-				&self,
-				ctx: Context,
-				tailstrict: bool,
-				handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,
-			) -> Result<()> {
-				let ($($gen,)*) = self;
-				$(
-					handler(&$gen.0, $gen.1.evaluate_arg(ctx.clone(), tailstrict)?)?;
-				)*
-				Ok(())
-			}
-			#[allow(non_snake_case)]
-			fn named_names(&self, handler: &mut dyn FnMut(&IStr)) {
-				let ($($gen,)*) = self;
-				$(
-					handler(&$gen.0);
-				)*
+			fn is_empty(&self) -> bool {
+				// impl_args_like only implements non-empty tuples.
+				false
 			}
 		}
-		impl<$($gen: ArgLike,)*> OptionalContext for ($((IStr, $gen),)*) where $($gen: OptionalContext),* {}
+		impl<$($gen: ArgLike,)*> OptionalContext for ($($gen,)*) where $($gen: OptionalContext),* {}
 	};
 	($count:expr; $($cur:ident)* @ $c:ident $($rest:ident)*) => {
 		impl_args_like!($count; $($cur)*);
@@ -342,5 +328,8 @@
 	}
 
 	fn named_names(&self, _handler: &mut dyn FnMut(&IStr)) {}
+	fn is_empty(&self) -> bool {
+		true
+	}
 }
 impl OptionalContext for () {}
modifiedcrates/jrsonnet-evaluator/src/function/mod.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/function/mod.rs
+++ b/crates/jrsonnet-evaluator/src/function/mod.rs
@@ -12,7 +12,10 @@
 	native::NativeDesc,
 	parse::{parse_default_function_call, parse_function_call},
 };
-use crate::{evaluate, evaluate_trivial, gc::TraceBox, tb, Context, ContextBuilder, Result, Val};
+use crate::{
+	bail, error::ErrorKind::*, evaluate, evaluate_trivial, gc::TraceBox, tb, Context,
+	ContextBuilder, Result, Thunk, Val,
+};
 
 pub mod arglike;
 pub mod builtin;
@@ -94,6 +97,8 @@
 	Id,
 	/// Plain function implemented in jsonnet.
 	Normal(Cc<FuncDesc>),
+	/// Function without arguments works just as a fancy thunk value.
+	Thunk(Thunk<Val>),
 	/// Standard library function.
 	StaticBuiltin(#[trace(skip)] &'static dyn StaticBuiltin),
 	/// User-provided function.
@@ -104,6 +109,7 @@
 	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 		match self {
 			Self::Id => f.debug_tuple("Id").finish(),
+			Self::Thunk(arg0) => f.debug_tuple("Thunk").field(arg0).finish(),
 			Self::Normal(arg0) => f.debug_tuple("Normal").field(arg0).finish(),
 			Self::StaticBuiltin(arg0) => {
 				f.debug_tuple("StaticBuiltin").field(&arg0.name()).finish()
@@ -146,6 +152,7 @@
 					)
 				})
 				.collect(),
+			Self::Thunk(_) => vec![],
 		}
 	}
 	/// Amount of non-default required arguments
@@ -155,6 +162,7 @@
 			Self::Normal(n) => n.params.iter().filter(|p| p.1.is_none()).count(),
 			Self::StaticBuiltin(i) => i.params().iter().filter(|p| !p.has_default()).count(),
 			Self::Builtin(i) => i.params().iter().filter(|p| !p.has_default()).count(),
+			Self::Thunk(_) => 0,
 		}
 	}
 	/// Function name, as defined in code.
@@ -164,6 +172,7 @@
 			Self::Normal(normal) => normal.name.clone(),
 			Self::StaticBuiltin(builtin) => builtin.name().into(),
 			Self::Builtin(builtin) => builtin.name().into(),
+			Self::Thunk(_) => "thunk".into(),
 		}
 	}
 	/// Call function using arguments evaluated in specified `call_ctx` [`Context`].
@@ -182,6 +191,12 @@
 				let body_ctx = func.call_body_context(call_ctx, args, tailstrict)?;
 				evaluate(body_ctx, &func.body)
 			}
+			Self::Thunk(thunk) => {
+				if args.is_empty() {
+					bail!(TooManyArgsFunctionHas(0, vec![],))
+				}
+				thunk.evaluate()
+			}
 			Self::StaticBuiltin(b) => b.call(call_ctx, loc, args),
 			Self::Builtin(b) => b.call(call_ctx, loc, args),
 		}
modifiedcrates/jrsonnet-evaluator/src/stdlib/format.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/stdlib/format.rs
+++ b/crates/jrsonnet-evaluator/src/stdlib/format.rs
@@ -308,22 +308,21 @@
 	prefix: &str,
 	caps: bool,
 ) {
-	let radix = radix as f64;
-	let iv = iv.floor();
+	let iv = iv.floor() as i64;
 	// Digit char indexes in reverse order, i.e
 	// for radix = 16 and n = 12f: [15, 2, 1]
-	let digits = if iv == 0.0 {
+	let digits = if iv == 0 {
 		vec![0u8]
 	} else {
 		let mut v = iv.abs();
 		let mut nums = Vec::with_capacity(1);
-		while v != 0.0 {
+		while v != 0 {
 			nums.push((v % radix) as u8);
-			v = (v / radix).floor();
+			v /= radix;
 		}
 		nums
 	};
-	let neg = iv < 0.0;
+	let neg = iv < 0;
 	#[allow(clippy::bool_to_int_with_if)]
 	let zp = padding.saturating_sub(if neg || blank || sign { 1 } else { 0 });
 	let zp2 = zp
modifiedcrates/jrsonnet-rowan-parser/src/ast.rsdiffbeforeafterboth
--- a/crates/jrsonnet-rowan-parser/src/ast.rs
+++ b/crates/jrsonnet-rowan-parser/src/ast.rs
@@ -16,12 +16,14 @@
 		Self: Sized;
 
 	fn syntax(&self) -> &SyntaxNode;
+	#[must_use]
 	fn clone_for_update(&self) -> Self
 	where
 		Self: Sized,
 	{
 		Self::cast(self.syntax().clone_for_update()).unwrap()
 	}
+	#[must_use]
 	fn clone_subtree(&self) -> Self
 	where
 		Self: Sized,
@@ -70,6 +72,8 @@
 }
 
 pub mod support {
+	use rowan::NodeOrToken;
+
 	use super::{AstChildren, AstNode, AstToken, SyntaxKind, SyntaxNode, SyntaxToken};
 
 	pub fn child<N: AstNode>(parent: &SyntaxNode) -> Option<N> {
@@ -89,7 +93,7 @@
 	pub fn token(parent: &SyntaxNode, kind: SyntaxKind) -> Option<SyntaxToken> {
 		parent
 			.children_with_tokens()
-			.filter_map(|it| it.into_token())
+			.filter_map(NodeOrToken::into_token)
 			.find(|it| it.kind() == kind)
 	}
 }
modifiedcrates/jrsonnet-rowan-parser/src/event.rsdiffbeforeafterboth
--- a/crates/jrsonnet-rowan-parser/src/event.rs
+++ b/crates/jrsonnet-rowan-parser/src/event.rs
@@ -26,7 +26,7 @@
 	// VirtualToken { kind: SyntaxKind },
 	/// Position of finished node
 	Finish {
-		/// Same as forward_parent of Start, but for wrapping
+		/// Same as `forward_parent` of Start, but for wrapping
 		wrapper: Option<NonZeroUsize>,
 		error: Option<Box<SyntaxError>>,
 	},
@@ -57,13 +57,14 @@
 		if self.offset == 0 {
 			return 0.into();
 		};
-		if let Some(lex) = self.lexemes.get(self.offset) {
-			lex.range.start()
-		} else if let Some(lex) = self.lexemes.get(self.offset - 1) {
-			lex.range.end()
-		} else {
-			panic!("hard oob")
-		}
+		self.lexemes.get(self.offset).map_or_else(
+			|| {
+				self.lexemes
+					.get(self.offset - 1)
+					.map_or_else(|| panic!("hard oob"), |lex| lex.range.end())
+			},
+			|lex| lex.range.start(),
+		)
 	}
 
 	pub(super) fn finish(mut self) -> Parse {
@@ -139,7 +140,7 @@
 						self.errors.push(LocatedSyntaxError {
 							error: *error,
 							range: TextRange::new(range.0, range.1),
-						})
+						});
 					}
 					self.builder.finish_node();
 					depth -= 1;
@@ -158,7 +159,7 @@
 								self.errors.push(LocatedSyntaxError {
 									error: *error,
 									range: TextRange::new(range.0, range.1),
-								})
+								});
 							}
 
 							if depth == 1 {
modifiedcrates/jrsonnet-stdlib/src/manifest/mod.rsdiffbeforeafterboth
--- a/crates/jrsonnet-stdlib/src/manifest/mod.rs
+++ b/crates/jrsonnet-stdlib/src/manifest/mod.rs
@@ -98,6 +98,7 @@
 }
 
 #[builtin]
+#[allow(clippy::fn_params_excessive_bools)]
 pub fn builtin_manifest_yaml_stream(
 	value: Val,
 	#[default(false)] indent_array_in_object: bool,
modifiedcrates/jrsonnet-stdlib/src/manifest/yaml.rsdiffbeforeafterboth
--- a/crates/jrsonnet-stdlib/src/manifest/yaml.rs
+++ b/crates/jrsonnet-stdlib/src/manifest/yaml.rs
@@ -76,7 +76,7 @@
 
 	string.is_empty()
 		|| need_quotes_spaces(string)
-		|| string.starts_with(|c| matches!(c, '&' | '*' | '?' | '|' | '-' | '<' | '>' | '=' | '!' | '%' | '@'))
+		|| string.starts_with(['&' , '*' , '?' , '|' , '-' , '<' , '>' , '=' , '!' , '%' , '@'])
 		|| string.contains(|c| matches!(c, ':' | '{' | '}' | '[' | ']' | ',' | '#' | '`' | '\"' | '\'' | '\\' | '\0'..='\x06' | '\t' | '\n' | '\r' | '\x0e'..='\x1a' | '\x1c'..='\x1f'))
 		|| [
 			// http://yaml.org/type/bool.html
modifiedcrates/jrsonnet-stdlib/src/strings.rsdiffbeforeafterboth
--- a/crates/jrsonnet-stdlib/src/strings.rs
+++ b/crates/jrsonnet-stdlib/src/strings.rs
@@ -267,6 +267,7 @@
 }
 
 #[cfg(test)]
+#[allow(clippy::float_cmp)]
 mod tests {
 	use super::*;
 
@@ -274,8 +275,8 @@
 	fn parse_nat_base_8() {
 		assert_eq!(parse_nat::<8>("0").unwrap(), 0.);
 		assert_eq!(parse_nat::<8>("5").unwrap(), 5.);
-		assert_eq!(parse_nat::<8>("32").unwrap(), 0o32 as f64);
-		assert_eq!(parse_nat::<8>("761").unwrap(), 0o761 as f64);
+		assert_eq!(parse_nat::<8>("32").unwrap(), f64::from(0o32));
+		assert_eq!(parse_nat::<8>("761").unwrap(), f64::from(0o761));
 	}
 
 	#[test]
@@ -290,7 +291,7 @@
 	fn parse_nat_base_16() {
 		assert_eq!(parse_nat::<16>("0").unwrap(), 0.);
 		assert_eq!(parse_nat::<16>("A").unwrap(), 10.);
-		assert_eq!(parse_nat::<16>("a9").unwrap(), 0xA9 as f64);
-		assert_eq!(parse_nat::<16>("BbC").unwrap(), 0xBBC as f64);
+		assert_eq!(parse_nat::<16>("a9").unwrap(), f64::from(0xA9));
+		assert_eq!(parse_nat::<16>("BbC").unwrap(), f64::from(0xBBC));
 	}
 }
modifiedcrates/jrsonnet-types/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-types/src/lib.rs
+++ b/crates/jrsonnet-types/src/lib.rs
@@ -4,84 +4,6 @@
 
 use jrsonnet_gcmodule::Trace;
 
-#[macro_export]
-macro_rules! ty {
-	((Array<number>)) => {{
-		$crate::ComplexValType::ArrayRef(&$crate::ComplexValType::Simple($crate::ValType::Num))
-	}};
-	((Array<ubyte>)) => {{
-		$crate::ComplexValType::ArrayRef(&$crate::ComplexValType::BoundedNumber(Some(0.0), Some(255.0)))
-	}};
-	(array) => {
-		$crate::ComplexValType::Simple($crate::ValType::Arr)
-	};
-	(boolean) => {
-		$crate::ComplexValType::Simple($crate::ValType::Bool)
-	};
-	(null) => {
-		$crate::ComplexValType::Simple($crate::ValType::Null)
-	};
-	(string) => {
-		$crate::ComplexValType::Simple($crate::ValType::Str)
-	};
-	(char) => {
-		$crate::ComplexValType::Char
-	};
-	(number) => {
-		$crate::ComplexValType::Simple($crate::ValType::Num)
-	};
-	(BoundedNumber<($min:expr), ($max:expr)>) => {{
-		$crate::ComplexValType::BoundedNumber($min, $max)
-	}};
-	(object) => {
-		$crate::ComplexValType::Simple($crate::ValType::Obj)
-	};
-	(any) => {
-		$crate::ComplexValType::Any
-	};
-	(function) => {
-		$crate::ComplexValType::Simple($crate::ValType::Func)
-	};
-	(($($a:tt) |+)) => {{
-		static CONTENTS: &'static [&'static $crate::ComplexValType] = &[
-			$(&ty!($a)),+
-		];
-		$crate::ComplexValType::UnionRef(CONTENTS)
-	}};
-	(($($a:tt) &+)) => {{
-		static CONTENTS: &'static [&'static $crate::ComplexValType] = &[
-			$(&ty!($a)),+
-		];
-		$crate::ComplexValType::SumRef(CONTENTS)
-	}};
-}
-
-#[test]
-fn test() {
-	assert_eq!(
-		ty!((Array<number>)),
-		ComplexValType::ArrayRef(&ComplexValType::Simple(ValType::Num))
-	);
-	assert_eq!(ty!(array), ComplexValType::Simple(ValType::Arr));
-	assert_eq!(ty!(any), ComplexValType::Any);
-	assert_eq!(
-		ty!((string | number)),
-		ComplexValType::UnionRef(&[
-			&ComplexValType::Simple(ValType::Str),
-			&ComplexValType::Simple(ValType::Num)
-		])
-	);
-	assert_eq!(
-		format!("{}", ty!(((string & number) | (object & null)))),
-		"string & number | object & null"
-	);
-	assert_eq!(format!("{}", ty!((string | array))), "string | array");
-	assert_eq!(
-		format!("{}", ty!(((string & number) | array))),
-		"string & number | array"
-	);
-}
-
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)]
 pub enum ValType {
 	Bool,
@@ -213,98 +135,5 @@
 			Self::Lazy(lazy) => write!(f, "Lazy<{lazy}>")?,
 		};
 		Ok(())
-	}
-}
-
-peg::parser! {
-pub grammar parser() for str {
-	rule number() -> f64
-		= n:$(['0'..='9']+) { n.parse().unwrap() }
-
-	rule any_ty() -> ComplexValType = "any" { ComplexValType::Any }
-	rule char_ty() -> ComplexValType = "character" { ComplexValType::Char }
-	rule bool_ty() -> ComplexValType = "boolean" { ComplexValType::Simple(ValType::Bool) }
-	rule null_ty() -> ComplexValType = "null" { ComplexValType::Simple(ValType::Null) }
-	rule str_ty() -> ComplexValType = "string" { ComplexValType::Simple(ValType::Str) }
-	rule num_ty() -> ComplexValType = "number" { ComplexValType::Simple(ValType::Num) }
-	rule simple_array_ty() -> ComplexValType = "array" { ComplexValType::Simple(ValType::Arr) }
-	rule simple_object_ty() -> ComplexValType = "object" { ComplexValType::Simple(ValType::Obj) }
-	rule simple_function_ty() -> ComplexValType = "function" { ComplexValType::Simple(ValType::Func) }
-
-	rule array_ty() -> ComplexValType
-		= "Array<" t:ty() ">" { ComplexValType::Array(Box::new(t)) }
-
-	rule bounded_number_ty() -> ComplexValType
-		= "BoundedNumber<" a:number() ", " b:number() ">" { ComplexValType::BoundedNumber(Some(a), Some(b)) }
-
-	rule ty_basic() -> ComplexValType
-		= any_ty()
-		/ char_ty()
-		/ bool_ty()
-		/ null_ty()
-		/ str_ty()
-		/ num_ty()
-		/ simple_array_ty()
-		/ simple_object_ty()
-		/ simple_function_ty()
-		/ array_ty()
-		/ bounded_number_ty()
-
-	pub rule ty() -> ComplexValType
-		= precedence! {
-			a:(@) " | " b:@ {
-				match a {
-					ComplexValType::Union(mut a) => {
-						a.push(b);
-						ComplexValType::Union(a)
-					}
-					_ => ComplexValType::Union(vec![a, b]),
-				}
-			}
-			--
-			a:(@) " & " b:@ {
-				match a {
-					ComplexValType::Sum(mut a) => {
-						a.push(b);
-						ComplexValType::Sum(a)
-					}
-					_ => ComplexValType::Sum(vec![a, b]),
-				}
-			}
-			--
-			"(" t:ty() ")" { t }
-			t:ty_basic() { t }
-		}
-}
-}
-
-#[cfg(test)]
-pub mod tests {
-	use super::parser;
-
-	#[test]
-	fn precedence() {
-		assert_eq!(
-			parser::ty("(any & any) | (any | any) & any")
-				.unwrap()
-				.to_string(),
-			"any & any | (any | any) & any"
-		);
-	}
-
-	#[test]
-	fn array() {
-		assert_eq!(parser::ty("Array<any>").unwrap().to_string(), "array");
-		assert_eq!(
-			parser::ty("Array<number>").unwrap().to_string(),
-			"Array<number>"
-		);
-	}
-	#[test]
-	fn bounded_number() {
-		assert_eq!(
-			parser::ty("BoundedNumber<1, 2>").unwrap().to_string(),
-			"BoundedNumber<1, 2>"
-		);
 	}
 }
modifiedflake.lockdiffbeforeafterboth
--- a/flake.lock
+++ b/flake.lock
@@ -7,11 +7,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1715274763,
-        "narHash": "sha256-3Iv1PGHJn9sV3HO4FlOVaaztOxa9uGLfOmUWrH7v7+A=",
+        "lastModified": 1724377159,
+        "narHash": "sha256-ixjje1JO8ucKT41hs6n2NCde1Vc0+Zc2p2gUbJpCsMw=",
         "owner": "ipetkov",
         "repo": "crane",
-        "rev": "27025ab71bdca30e7ed0a16c88fd74c5970fc7f5",
+        "rev": "3e47b7a86c19142bd3675da49d6acef488b4dac1",
         "type": "github"
       },
       "original": {
@@ -27,44 +27,26 @@
         ]
       },
       "locked": {
-        "lastModified": 1717285511,
-        "narHash": "sha256-iKzJcpdXih14qYVcZ9QC9XuZYnPc6T8YImb6dX166kw=",
+        "lastModified": 1722555600,
+        "narHash": "sha256-XOQkdLafnb/p9ij77byFQjDf5m5QYl9b2REiVClC+x4=",
         "owner": "hercules-ci",
         "repo": "flake-parts",
-        "rev": "2a55567fcf15b1b1c7ed712a2c6fadaec7412ea8",
+        "rev": "8471fe90ad337a8074e957b69ca4d0089218391d",
         "type": "github"
       },
       "original": {
         "owner": "hercules-ci",
         "repo": "flake-parts",
-        "type": "github"
-      }
-    },
-    "flake-utils": {
-      "inputs": {
-        "systems": "systems"
-      },
-      "locked": {
-        "lastModified": 1710146030,
-        "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
-        "owner": "numtide",
-        "repo": "flake-utils",
-        "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
-        "type": "github"
-      },
-      "original": {
-        "owner": "numtide",
-        "repo": "flake-utils",
         "type": "github"
       }
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1715551360,
-        "narHash": "sha256-fGYt2XnTYUS4Q0eH8tVu3ki1+m9YTgZ+NjlfkMKzko0=",
+        "lastModified": 1724519568,
+        "narHash": "sha256-CmfrenY4cEi/mIslKy8XOGdqxUUVgT6/qMzNcAN/7z8=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "836306cd7bbb9e0f89c557b2ae14df09e573ee89",
+        "rev": "eb0e6df0cdd2641ec0651cd9802ff4cff3b3e915",
         "type": "github"
       },
       "original": {
@@ -84,17 +66,16 @@
     },
     "rust-overlay": {
       "inputs": {
-        "flake-utils": "flake-utils",
         "nixpkgs": [
           "nixpkgs"
         ]
       },
       "locked": {
-        "lastModified": 1715480255,
-        "narHash": "sha256-gEZl8nYidQwqJhOigJ91JDjoBFoPEWVsd82AKnaE7Go=",
+        "lastModified": 1724466314,
+        "narHash": "sha256-ltKuK6shQ64uej1mYNtBsDYxttUNFiv9AcHqk0+0NQM=",
         "owner": "oxalica",
         "repo": "rust-overlay",
-        "rev": "d690205a4f01ec0930303c4204e5063958e51255",
+        "rev": "2b5b3edd96ef336b00622dcabc13788fdef9e3ca",
         "type": "github"
       },
       "original": {
@@ -123,21 +104,6 @@
       "original": {
         "owner": "CertainLach",
         "repo": "shelly",
-        "type": "github"
-      }
-    },
-    "systems": {
-      "locked": {
-        "lastModified": 1681028828,
-        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
-        "owner": "nix-systems",
-        "repo": "default",
-        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
-        "type": "github"
-      },
-      "original": {
-        "owner": "nix-systems",
-        "repo": "default",
         "type": "github"
       }
     }
modifiedrust-toolchain.tomldiffbeforeafterboth
--- a/rust-toolchain.toml
+++ b/rust-toolchain.toml
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2024-05-10"
+channel = "nightly-2024-08-20"
 components = ["rustfmt", "clippy", "rust-analyzer", "rust-src"]
modifiedtests/tests/builtin.rsdiffbeforeafterboth
--- a/tests/tests/builtin.rs
+++ b/tests/tests/builtin.rs
@@ -11,8 +11,8 @@
 use jrsonnet_stdlib::ContextInitializer as StdContextInitializer;
 
 #[builtin]
-fn a() -> Result<u32> {
-	Ok(1)
+fn a() -> u32 {
+	1
 }
 
 #[test]
@@ -29,8 +29,8 @@
 }
 
 #[builtin]
-fn native_add(a: u32, b: u32) -> Result<u32> {
-	Ok(a + b)
+fn native_add(a: u32, b: u32) -> u32 {
+	a + b
 }
 #[derive(Trace)]
 struct NativeAddContextInitializer;
@@ -72,13 +72,13 @@
 #[builtin(fields(
     a: u32
 ))]
-fn curried_add(this: &curried_add, b: u32) -> Result<u32> {
-	Ok(this.a + b)
+fn curried_add(this: &curried_add, b: u32) -> u32 {
+	this.a + b
 }
 
 #[builtin]
-fn curry_add(a: u32) -> Result<FuncVal> {
-	Ok(FuncVal::builtin(curried_add { a }))
+fn curry_add(a: u32) -> FuncVal {
+	FuncVal::builtin(curried_add { a })
 }
 #[derive(Trace)]
 struct CurryAddContextInitializer;
modifiedtests/tests/common.rsdiffbeforeafterboth
--- a/tests/tests/common.rs
+++ b/tests/tests/common.rs
@@ -73,6 +73,7 @@
 			.iter()
 			.map(|p| p.name().as_str().unwrap_or("<unnamed>").to_string())
 			.collect(),
+		FuncVal::Thunk(_) => vec![],
 	}
 }
 
modifiedtests/tests/golden.rsdiffbeforeafterboth
--- a/tests/tests/golden.rs
+++ b/tests/tests/golden.rs
@@ -32,7 +32,7 @@
 		Err(e) => return trace_format.format(&e).unwrap(),
 	};
 	match v.manifest(JsonFormat::default()) {
-		Ok(v) => v.to_string(),
+		Ok(v) => v,
 		Err(e) => trace_format.format(&e).unwrap(),
 	}
 }
@@ -57,45 +57,46 @@
 
 		if !golden_path.exists() {
 			fs::write(golden_path, &result)?;
-		} else {
-			let golden = fs::read_to_string(golden_path)?;
+			continue;
+		}
 
-			match (serde_json::from_str(&result), serde_json::from_str(&golden)) {
-				(Err(_), Ok(_)) => assert_eq!(
-					result,
-					golden,
-					"unexpected error for golden {}",
-					entry.path().display()
-				),
-				(Ok(_), Err(_)) => assert_eq!(
-					result,
-					golden,
-					"expected error for golden {}",
-					entry.path().display()
-				),
-				(Ok(result), Ok(golden)) => {
-					// Show diff relative to golden`.
-					let diff = JsonDiff::diff_string(&golden, &result, false);
-					if let Some(diff) = diff {
-						panic!(
-							"Result \n{result:#}\n\
-								and golden \n{golden:#}\n\
-								did not match structurally:\n{diff:#}\n\
-								for golden {}",
-							entry.path().display()
-						);
-					}
-				}
-				(Err(_), Err(_)) => {}
-			};
+		let golden = fs::read_to_string(golden_path)?;
 
-			assert_eq!(
+		match (serde_json::from_str(&result), serde_json::from_str(&golden)) {
+			(Err(_), Ok(_)) => assert_eq!(
 				result,
 				golden,
-				"golden didn't match for {}",
+				"unexpected error for golden {}",
+				entry.path().display()
+			),
+			(Ok(_), Err(_)) => assert_eq!(
+				result,
+				golden,
+				"expected error for golden {}",
 				entry.path().display()
-			)
-		}
+			),
+			(Ok(result), Ok(golden)) => {
+				// Show diff relative to golden`.
+				let diff = JsonDiff::diff_string(&golden, &result, false);
+				if let Some(diff) = diff {
+					panic!(
+						"Result \n{result:#}\n\
+							and golden \n{golden:#}\n\
+							did not match structurally:\n{diff:#}\n\
+							for golden {}",
+						entry.path().display()
+					);
+				}
+			}
+			(Err(_), Err(_)) => {}
+		};
+
+		assert_eq!(
+			result,
+			golden,
+			"golden didn't match for {}",
+			entry.path().display()
+		);
 	}
 
 	Ok(())