git.delta.rocks / jrsonnet / refs/commits / 70f37833046b

difftreelog

style fix clippy warnings

Yaroslav Bolyukin2022-10-11parent: #afca252.patch.diff
in: master

20 files changed

modifiedbindings/jsonnet/src/lib.rsdiffbeforeafterboth
--- a/bindings/jsonnet/src/lib.rs
+++ b/bindings/jsonnet/src/lib.rs
@@ -70,6 +70,7 @@
 
 /// Creates a new Jsonnet virtual machine.
 #[no_mangle]
+#[allow(clippy::box_default)]
 pub extern "C" fn jsonnet_make() -> *mut State {
 	let state = State::default();
 	state.settings_mut().import_resolver = Box::new(FileImportResolver::default());
modifiedcrates/jrsonnet-cli/src/stdlib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-cli/src/stdlib.rs
+++ b/crates/jrsonnet-cli/src/stdlib.rs
@@ -44,7 +44,7 @@
 		if out.len() != 2 {
 			return Err("bad ext-file syntax".to_owned());
 		}
-		let file = read_to_string(&out[1]);
+		let file = read_to_string(out[1]);
 		match file {
 			Ok(content) => Ok(Self {
 				name: out[0].into(),
modifiedcrates/jrsonnet-evaluator/src/error.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/error.rs
+++ b/crates/jrsonnet-evaluator/src/error.rs
@@ -100,7 +100,7 @@
 	#[error("duplicate local var: {0}")]
 	DuplicateLocalVar(IStr),
 
-	#[error("type mismatch: expected {}, got {2} {0}", .1.iter().map(|e| format!("{}", e)).collect::<Vec<_>>().join(", "))]
+	#[error("type mismatch: expected {}, got {2} {0}", .1.iter().map(|e| format!("{e}")).collect::<Vec<_>>().join(", "))]
 	TypeMismatch(&'static str, Vec<ValType>, ValType),
 	#[error("no such field: {}{}", format_empty_str(.0), format_found(.1, "field"))]
 	NoSuchField(IStr, Vec<IStr>),
@@ -113,7 +113,7 @@
 	BindingParameterASecondTime(IStr),
 	#[error("too many args, function has {0}{}", format_signature(.1))]
 	TooManyArgsFunctionHas(usize, FunctionSignature),
-	#[error("function argument is not passed: {}{}", .0.as_ref().map(|n| n.as_str()).unwrap_or("<unnamed>"), format_signature(.1))]
+	#[error("function argument is not passed: {}{}", .0.as_ref().map_or("<unnamed>", IStr::as_str), format_signature(.1))]
 	FunctionParameterNotBoundInCall(Option<IStr>, FunctionSignature),
 
 	#[error("external variable is not defined: {0}")]
@@ -249,7 +249,7 @@
 	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 		writeln!(f, "{}", self.0 .0)?;
 		for el in &self.0 .1 .0 {
-			writeln!(f, "\t{:?}", el)?;
+			writeln!(f, "\t{el:?}")?;
 		}
 		Ok(())
 	}
modifiedcrates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/evaluate/mod.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/mod.rs
@@ -436,7 +436,7 @@
 		UnaryOp(o, v) => evaluate_unary_op(*o, &evaluate(s, ctx, v)?)?,
 		Var(name) => s.push(
 			CallLocation::new(loc),
-			|| format!("variable <{}> access", name),
+			|| format!("variable <{name}> access"),
 			|| ctx.binding(name.clone())?.evaluate(s.clone()),
 		)?,
 		Index(value, index) => {
@@ -446,7 +446,7 @@
 			) {
 				(Val::Obj(v), Val::Str(key)) => s.push(
 					CallLocation::new(loc),
-					|| format!("field <{}> access", key),
+					|| format!("field <{key}> access"),
 					|| match v.get(s.clone(), key.clone()) {
 						Ok(Some(v)) => Ok(v),
 						#[cfg(not(feature = "friendly-errors"))]
@@ -611,7 +611,7 @@
 				if let Some(value) = expr {
 					Ok(Some(s.push(
 						loc,
-						|| format!("slice {}", desc),
+						|| format!("slice {desc}"),
 						|| T::from_untyped(evaluate(s.clone(), ctx.clone(), value)?, s.clone()),
 					)?))
 				} else {
modifiedcrates/jrsonnet-evaluator/src/evaluate/operator.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/evaluate/operator.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/operator.rs
@@ -30,8 +30,8 @@
 		(Str(a), Num(b)) => Str(format!("{a}{b}").into()),
 
 		(Str(a), o) | (o, Str(a)) if a.is_empty() => Val::Str(o.clone().to_string(s)?),
-		(Str(a), o) => Str(format!("{}{}", a, o.clone().to_string(s)?).into()),
-		(o, Str(a)) => Str(format!("{}{}", o.clone().to_string(s)?, a).into()),
+		(Str(a), o) => Str(format!("{a}{}", o.clone().to_string(s)?).into()),
+		(o, Str(a)) => Str(format!("{}{a}", o.clone().to_string(s)?).into()),
 
 		(Obj(v1), Obj(v2)) => Obj(v2.extend_from(v1.clone())),
 		(Arr(a), Arr(b)) => {
modifiedcrates/jrsonnet-evaluator/src/function/arglike.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/function/arglike.rs
+++ b/crates/jrsonnet-evaluator/src/function/arglike.rs
@@ -108,7 +108,7 @@
 		handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,
 	) -> Result<()> {
 		for (idx, el) in self.iter().enumerate() {
-			handler(idx, Thunk::evaluated(el.clone()))?
+			handler(idx, Thunk::evaluated(el.clone()))?;
 		}
 		Ok(())
 	}
modifiedcrates/jrsonnet-evaluator/src/function/parse.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/function/parse.rs
+++ b/crates/jrsonnet-evaluator/src/function/parse.rs
@@ -179,12 +179,7 @@
 		// FIXME: O(n) for arg existence check
 		let id = params
 			.iter()
-			.position(|p| {
-				p.name
-					.as_ref()
-					.map(|v| &v as &str == name as &str)
-					.unwrap_or(false)
-			})
+			.position(|p| p.name.as_ref().map_or(false, |v| v as &str == name as &str))
 			.ok_or_else(|| UnknownFunctionParameter((name as &str).to_owned()))?;
 		if replace(&mut passed_args[id], Some(arg)).is_some() {
 			throw!(BindingParameterASecondTime(name.clone()));
@@ -209,8 +204,7 @@
 					if param
 						.name
 						.as_ref()
-						.map(|v| &v as &str == name as &str)
-						.unwrap_or(false)
+						.map_or(false, |v| v as &str == name as &str)
 					{
 						found = true;
 					}
modifiedcrates/jrsonnet-evaluator/src/import.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/import.rs
+++ b/crates/jrsonnet-evaluator/src/import.rs
@@ -123,15 +123,11 @@
 		};
 		if meta.is_file() {
 			Ok(SourcePath::new(SourceFile::new(
-				path.canonicalize()
-					.map_err(|e| ImportIo(e.to_string()))?
-					.to_owned(),
+				path.canonicalize().map_err(|e| ImportIo(e.to_string()))?,
 			)))
 		} else if meta.is_dir() {
 			Ok(SourcePath::new(SourceDirectory::new(
-				path.canonicalize()
-					.map_err(|e| ImportIo(e.to_string()))?
-					.to_owned(),
+				path.canonicalize().map_err(|e| ImportIo(e.to_string()))?,
 			)))
 		} else {
 			unreachable!("this can't be a symlink")
modifiedcrates/jrsonnet-evaluator/src/integrations/serde.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/integrations/serde.rs
+++ b/crates/jrsonnet-evaluator/src/integrations/serde.rs
@@ -16,7 +16,7 @@
 			Self::Null => Val::Null,
 			Self::Bool(v) => Val::Bool(v),
 			Self::Number(n) => Val::Num(n.as_f64().ok_or_else(|| {
-				RuntimeError(format!("json number can't be represented as jsonnet: {}", n).into())
+				RuntimeError(format!("json number can't be represented as jsonnet: {n}").into())
 			})?),
 			Self::String(s) => Val::Str((&s as &str).into()),
 			Self::Array(a) => {
modifiedcrates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/lib.rs
+++ b/crates/jrsonnet-evaluator/src/lib.rs
@@ -594,7 +594,7 @@
 			.insert(name, TlaArg::String(value));
 	}
 	pub fn add_tla_code(&self, name: IStr, code: &str) -> Result<()> {
-		let source_name = format!("<top-level-arg:{}>", name);
+		let source_name = format!("<top-level-arg:{name}>");
 		let source = Source::new_virtual(source_name.into(), code.into());
 		let parsed = jrsonnet_parser::parse(
 			code,
modifiedcrates/jrsonnet-evaluator/src/obj.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/obj.rs
+++ b/crates/jrsonnet-evaluator/src/obj.rs
@@ -156,9 +156,9 @@
 	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 		if let Some(super_obj) = self.0.sup.as_ref() {
 			if f.alternate() {
-				write!(f, "{:#?}", super_obj)?;
+				write!(f, "{super_obj:#?}")?;
 			} else {
-				write!(f, "{:?}", super_obj)?;
+				write!(f, "{super_obj:?}")?;
 			}
 			write!(f, " + ")?;
 		}
@@ -395,10 +395,9 @@
 			})?;
 		self.0.value_cache.borrow_mut().insert(
 			key,
-			match &value {
-				Some(v) => CacheValue::Cached(v.clone()),
-				None => CacheValue::NotFound,
-			},
+			value
+				.as_ref()
+				.map_or(CacheValue::NotFound, |v| CacheValue::Cached(v.clone())),
 		);
 		Ok(value)
 	}
modifiedcrates/jrsonnet-evaluator/src/stdlib/format.rsdiffbeforeafterboth
before · crates/jrsonnet-evaluator/src/stdlib/format.rs
1//! faster std.format impl2#![allow(clippy::too_many_arguments)]34use jrsonnet_gcmodule::Trace;5use jrsonnet_interner::IStr;6use jrsonnet_types::ValType;7use thiserror::Error;89use crate::{error::Error::*, throw, typed::Typed, LocError, ObjValue, Result, State, Val};1011#[derive(Debug, Clone, Error, Trace)]12pub enum FormatError {13	#[error("truncated format code")]14	TruncatedFormatCode,15	#[error("unrecognized conversion type: {0}")]16	UnrecognizedConversionType(char),1718	#[error("not enough values")]19	NotEnoughValues,2021	#[error("cannot use * width with object")]22	CannotUseStarWidthWithObject,23	#[error("mapping keys required")]24	MappingKeysRequired,25	#[error("no such format field: {0}")]26	NoSuchFormatField(IStr),27}2829impl From<FormatError> for LocError {30	fn from(e: FormatError) -> Self {31		Self::new(Format(e))32	}33}3435use FormatError::*;3637type ParseResult<'t, T> = std::result::Result<(T, &'t str), FormatError>;3839pub fn try_parse_mapping_key(str: &str) -> ParseResult<&str> {40	if str.is_empty() {41		return Err(TruncatedFormatCode);42	}43	let bytes = str.as_bytes();44	if bytes[0] == b'(' {45		let mut i = 1;46		while i < bytes.len() {47			if bytes[i] == b')' {48				return Ok((&str[1..i as usize], &str[i as usize + 1..]));49			}50			i += 1;51		}52		Err(TruncatedFormatCode)53	} else {54		Ok(("", str))55	}56}5758#[cfg(test)]59pub mod tests_key {60	use super::*;6162	#[test]63	fn parse_key() {64		assert_eq!(65			try_parse_mapping_key("(hello ) world").unwrap(),66			("hello ", " world")67		);68		assert_eq!(try_parse_mapping_key("() world").unwrap(), ("", " world"));69		assert_eq!(try_parse_mapping_key(" world").unwrap(), ("", " world"));70		assert_eq!(71			try_parse_mapping_key(" () world").unwrap(),72			("", " () world")73		);74	}7576	#[test]77	#[should_panic]78	fn parse_key_missing_start() {79		try_parse_mapping_key("").unwrap();80	}8182	#[test]83	#[should_panic]84	fn parse_key_missing_end() {85		try_parse_mapping_key("(   ").unwrap();86	}87}8889#[allow(clippy::struct_excessive_bools)]90#[derive(Default, Debug)]91pub struct CFlags {92	pub alt: bool,93	pub zero: bool,94	pub left: bool,95	pub blank: bool,96	pub sign: bool,97}9899pub fn try_parse_cflags(str: &str) -> ParseResult<CFlags> {100	if str.is_empty() {101		return Err(TruncatedFormatCode);102	}103	let bytes = str.as_bytes();104	let mut i = 0;105	let mut out = CFlags::default();106	loop {107		if bytes.len() == i {108			return Err(TruncatedFormatCode);109		}110		match bytes[i] {111			b'#' => out.alt = true,112			b'0' => out.zero = true,113			b'-' => out.left = true,114			b' ' => out.blank = true,115			b'+' => out.sign = true,116			_ => break,117		}118		i += 1;119	}120	Ok((out, &str[i..]))121}122123#[derive(Debug, PartialEq, Eq)]124pub enum Width {125	Star,126	Fixed(usize),127}128pub fn try_parse_field_width(str: &str) -> ParseResult<Width> {129	if str.is_empty() {130		return Err(TruncatedFormatCode);131	}132	let bytes = str.as_bytes();133	if bytes[0] == b'*' {134		return Ok((Width::Star, &str[1..]));135	}136	let mut out: usize = 0;137	let mut digits = 0;138	while let Some(digit) = (bytes[digits] as char).to_digit(10) {139		out *= 10;140		out += digit as usize;141		digits += 1;142		if digits == bytes.len() {143			return Err(TruncatedFormatCode);144		}145	}146	Ok((Width::Fixed(out), &str[digits..]))147}148149pub fn try_parse_precision(str: &str) -> ParseResult<Option<Width>> {150	if str.is_empty() {151		return Err(TruncatedFormatCode);152	}153	let bytes = str.as_bytes();154	if bytes[0] == b'.' {155		try_parse_field_width(&str[1..]).map(|(r, s)| (Some(r), s))156	} else {157		Ok((None, str))158	}159}160161// Only skips162pub fn try_parse_length_modifier(str: &str) -> ParseResult<()> {163	if str.is_empty() {164		return Err(TruncatedFormatCode);165	}166	let bytes = str.as_bytes();167	let mut idx = 0;168	while bytes[idx] == b'h' || bytes[idx] == b'l' || bytes[idx] == b'L' {169		idx += 1;170		if bytes.len() == idx {171			return Err(TruncatedFormatCode);172		}173	}174	Ok(((), &str[idx..]))175}176177#[derive(Debug, PartialEq, Eq)]178pub enum ConvTypeV {179	Decimal,180	Octal,181	Hexadecimal,182	Scientific,183	Float,184	Shorter,185	Char,186	String,187	Percent,188}189pub struct ConvType {190	v: ConvTypeV,191	caps: bool,192}193194pub fn parse_conversion_type(str: &str) -> ParseResult<ConvType> {195	if str.is_empty() {196		return Err(TruncatedFormatCode);197	}198199	let code = str.as_bytes()[0];200	let v: (ConvTypeV, bool) = match code {201		b'd' | b'i' | b'u' => (ConvTypeV::Decimal, false),202		b'o' => (ConvTypeV::Octal, false),203		b'x' => (ConvTypeV::Hexadecimal, false),204		b'X' => (ConvTypeV::Hexadecimal, true),205		b'e' => (ConvTypeV::Scientific, false),206		b'E' => (ConvTypeV::Scientific, true),207		b'f' => (ConvTypeV::Float, false),208		b'F' => (ConvTypeV::Float, true),209		b'g' => (ConvTypeV::Shorter, false),210		b'G' => (ConvTypeV::Shorter, true),211		b'c' => (ConvTypeV::Char, false),212		b's' => (ConvTypeV::String, false),213		b'%' => (ConvTypeV::Percent, false),214		c => return Err(UnrecognizedConversionType(c as char)),215	};216217	Ok((ConvType { v: v.0, caps: v.1 }, &str[1..]))218}219220#[derive(Debug)]221pub struct Code<'s> {222	mkey: &'s str,223	cflags: CFlags,224	width: Width,225	precision: Option<Width>,226	convtype: ConvTypeV,227	caps: bool,228}229pub fn parse_code(str: &str) -> ParseResult<Code> {230	if str.is_empty() {231		return Err(TruncatedFormatCode);232	}233	let (mkey, str) = try_parse_mapping_key(str)?;234	let (cflags, str) = try_parse_cflags(str)?;235	let (width, str) = try_parse_field_width(str)?;236	let (precision, str) = try_parse_precision(str)?;237	let (_, str) = try_parse_length_modifier(str)?;238	let (convtype, str) = parse_conversion_type(str)?;239240	Ok((241		Code {242			mkey,243			cflags,244			width,245			precision,246			convtype: convtype.v,247			caps: convtype.caps,248		},249		str,250	))251}252253#[derive(Debug)]254pub enum Element<'s> {255	String(&'s str),256	Code(Code<'s>),257}258pub fn parse_codes(mut str: &str) -> Result<Vec<Element>> {259	let mut bytes = str.as_bytes();260	let mut out = vec![];261	let mut offset = 0;262263	loop {264		while offset != bytes.len() && bytes[offset] != b'%' {265			offset += 1;266		}267		if offset != 0 {268			out.push(Element::String(&str[0..offset]));269		}270		if offset == bytes.len() {271			return Ok(out);272		}273		str = &str[offset + 1..];274		let code;275		(code, str) = parse_code(str)?;276		bytes = str.as_bytes();277		offset = 0;278279		out.push(Element::Code(code));280	}281}282283const NUMBERS: &[u8] = b"0123456789abcdefghijklmnopqrstuvwxyz";284285#[inline]286pub fn render_integer(287	out: &mut String,288	iv: f64,289	padding: usize,290	precision: usize,291	blank: bool,292	sign: bool,293	radix: i64,294	prefix: &str,295	caps: bool,296) {297	let radix = radix as f64;298	let iv = iv.floor();299	// Digit char indexes in reverse order, i.e300	// for radix = 16 and n = 12f: [15, 2, 1]301	let digits = if iv == 0.0 {302		vec![0u8]303	} else {304		let mut v = iv.abs();305		let mut nums = Vec::with_capacity(1);306		while v != 0.0 {307			nums.push((v % radix) as u8);308			v = (v / radix).floor();309		}310		nums311	};312	let neg = iv < 0.0;313	let zp = padding.saturating_sub(if neg || blank || sign { 1 } else { 0 });314	let zp2 = zp315		.max(precision)316		.saturating_sub(prefix.len() + digits.len());317318	if neg {319		out.push('-');320	} else if sign {321		out.push('+');322	} else if blank {323		out.push(' ');324	}325326	out.reserve(zp2);327	for _ in 0..zp2 {328		out.push('0');329	}330	out.push_str(prefix);331332	for digit in digits.into_iter().rev() {333		let ch = NUMBERS[digit as usize] as char;334		out.push(if caps { ch.to_ascii_uppercase() } else { ch });335	}336}337338pub fn render_decimal(339	out: &mut String,340	iv: f64,341	padding: usize,342	precision: usize,343	blank: bool,344	sign: bool,345) {346	render_integer(out, iv, padding, precision, blank, sign, 10, "", false);347}348pub fn render_octal(349	out: &mut String,350	iv: f64,351	padding: usize,352	precision: usize,353	alt: bool,354	blank: bool,355	sign: bool,356) {357	render_integer(358		out,359		iv,360		padding,361		precision,362		blank,363		sign,364		8,365		if alt && iv != 0.0 { "0" } else { "" },366		false,367	);368}369370#[allow(clippy::fn_params_excessive_bools)]371pub fn render_hexadecimal(372	out: &mut String,373	iv: f64,374	padding: usize,375	precision: usize,376	alt: bool,377	blank: bool,378	sign: bool,379	caps: bool,380) {381	render_integer(382		out,383		iv,384		padding,385		precision,386		blank,387		sign,388		16,389		match (alt, caps) {390			(true, true) => "0X",391			(true, false) => "0x",392			(false, _) => "",393		},394		caps,395	);396}397398#[allow(clippy::fn_params_excessive_bools)]399pub fn render_float(400	out: &mut String,401	n: f64,402	mut padding: usize,403	precision: usize,404	blank: bool,405	sign: bool,406	ensure_pt: bool,407	trailing: bool,408) {409	let dot_size = if precision == 0 && !ensure_pt { 0 } else { 1 };410	padding = padding.saturating_sub(dot_size + precision);411	render_decimal(out, n.floor(), padding, 0, blank, sign);412	if precision == 0 {413		if ensure_pt {414			out.push('.');415		}416		return;417	}418	let frac = n419		.fract()420		.mul_add(10.0_f64.powf(precision as f64), 0.5)421		.floor();422	if trailing || frac > 0.0 {423		out.push('.');424		let mut frac_str = String::new();425		render_decimal(&mut frac_str, frac, precision, 0, false, false);426		let mut trim = frac_str.len();427		if !trailing {428			for b in frac_str.as_bytes().iter().rev() {429				if *b == b'0' {430					trim -= 1;431				}432			}433		}434		out.push_str(&frac_str[..trim]);435	} else if ensure_pt {436		out.push('.');437	}438}439440#[allow(clippy::fn_params_excessive_bools)]441pub fn render_float_sci(442	out: &mut String,443	n: f64,444	mut padding: usize,445	precision: usize,446	blank: bool,447	sign: bool,448	ensure_pt: bool,449	trailing: bool,450	caps: bool,451) {452	let exponent = n.log10().floor();453	let mantissa = if exponent as i16 == -324 {454		n * 10.0 / 10.0_f64.powf(exponent + 1.0)455	} else {456		n / 10.0_f64.powf(exponent)457	};458	let mut exponent_str = String::new();459	render_decimal(&mut exponent_str, exponent, 3, 0, false, true);460461	// +1 for e462	padding = padding.saturating_sub(exponent_str.len() + 1);463464	render_float(465		out, mantissa, padding, precision, blank, sign, ensure_pt, trailing,466	);467	out.push(if caps { 'E' } else { 'e' });468	out.push_str(&exponent_str);469}470471#[allow(clippy::too_many_lines)]472pub fn format_code(473	s: State,474	out: &mut String,475	value: &Val,476	code: &Code,477	width: usize,478	precision: Option<usize>,479) -> Result<()> {480	let clfags = &code.cflags;481	let (fpprec, iprec) = match precision {482		Some(v) => (v, v),483		None => (6, 0),484	};485	let padding = if clfags.zero && !clfags.left {486		width487	} else {488		0489	};490491	// TODO: If left padded, can optimize by writing directly to out492	let mut tmp_out = String::new();493494	match code.convtype {495		ConvTypeV::String => tmp_out.push_str(&value.clone().to_string(s)?),496		ConvTypeV::Decimal => {497			let value = f64::from_untyped(value.clone(), s)?;498			render_decimal(499				&mut tmp_out,500				value,501				padding,502				iprec,503				clfags.blank,504				clfags.sign,505			);506		}507		ConvTypeV::Octal => {508			let value = f64::from_untyped(value.clone(), s)?;509			render_octal(510				&mut tmp_out,511				value,512				padding,513				iprec,514				clfags.alt,515				clfags.blank,516				clfags.sign,517			);518		}519		ConvTypeV::Hexadecimal => {520			let value = f64::from_untyped(value.clone(), s)?;521			render_hexadecimal(522				&mut tmp_out,523				value,524				padding,525				iprec,526				clfags.alt,527				clfags.blank,528				clfags.sign,529				code.caps,530			);531		}532		ConvTypeV::Scientific => {533			let value = f64::from_untyped(value.clone(), s)?;534			render_float_sci(535				&mut tmp_out,536				value,537				padding,538				fpprec,539				clfags.blank,540				clfags.sign,541				clfags.alt,542				true,543				code.caps,544			);545		}546		ConvTypeV::Float => {547			let value = f64::from_untyped(value.clone(), s)?;548			render_float(549				&mut tmp_out,550				value,551				padding,552				fpprec,553				clfags.blank,554				clfags.sign,555				clfags.alt,556				true,557			);558		}559		ConvTypeV::Shorter => {560			let value = f64::from_untyped(value.clone(), s)?;561			let exponent = value.log10().floor();562			if exponent < -4.0 || exponent >= fpprec as f64 {563				render_float_sci(564					&mut tmp_out,565					value,566					padding,567					fpprec - 1,568					clfags.blank,569					clfags.sign,570					clfags.alt,571					clfags.alt,572					code.caps,573				);574			} else {575				let digits_before_pt = 1.max(exponent as usize + 1);576				render_float(577					&mut tmp_out,578					value,579					padding,580					fpprec - digits_before_pt,581					clfags.blank,582					clfags.sign,583					clfags.alt,584					clfags.alt,585				);586			}587		}588		ConvTypeV::Char => match value.clone() {589			Val::Num(n) => tmp_out590				.push(std::char::from_u32(n as u32).ok_or(InvalidUnicodeCodepointGot(n as u32))?),591			Val::Str(s) => {592				if s.chars().count() != 1 {593					throw!(RuntimeError(594						format!("%c expected 1 char string, got {}", s.chars().count()).into(),595					));596				}597				tmp_out.push_str(&s);598			}599			_ => {600				throw!(TypeMismatch(601					"%c requires number/string",602					vec![ValType::Num, ValType::Str],603					value.value_type(),604				));605			}606		},607		ConvTypeV::Percent => tmp_out.push('%'),608	};609610	let padding = width.saturating_sub(tmp_out.len());611612	if !clfags.left {613		for _ in 0..padding {614			out.push(' ');615		}616	}617	out.push_str(&tmp_out);618	if clfags.left {619		for _ in 0..padding {620			out.push(' ');621		}622	}623624	Ok(())625}626627pub fn format_arr(s: State, str: &str, mut values: &[Val]) -> Result<String> {628	let codes = parse_codes(str)?;629	let mut out = String::new();630631	for code in codes {632		match code {633			Element::String(s) => {634				out.push_str(s);635			}636			Element::Code(c) => {637				let width = match c.width {638					Width::Star => {639						if values.is_empty() {640							throw!(NotEnoughValues);641						}642						let value = &values[0];643						values = &values[1..];644						usize::from_untyped(value.clone(), s.clone())?645					}646					Width::Fixed(n) => n,647				};648				let precision = match c.precision {649					Some(Width::Star) => {650						if values.is_empty() {651							throw!(NotEnoughValues);652						}653						let value = &values[0];654						values = &values[1..];655						Some(usize::from_untyped(value.clone(), s.clone())?)656					}657					Some(Width::Fixed(n)) => Some(n),658					None => None,659				};660661				// %% should not consume a value662				let value = if c.convtype == ConvTypeV::Percent {663					&Val::Null664				} else {665					if values.is_empty() {666						throw!(NotEnoughValues);667					}668					let value = &values[0];669					values = &values[1..];670					value671				};672673				format_code(s.clone(), &mut out, value, &c, width, precision)?;674			}675		}676	}677678	Ok(out)679}680681pub fn format_obj(s: State, str: &str, values: &ObjValue) -> Result<String> {682	let codes = parse_codes(str)?;683	let mut out = String::new();684685	for code in codes {686		match code {687			Element::String(s) => {688				out.push_str(s);689			}690			Element::Code(c) => {691				// TODO: Operate on ref692				let f: IStr = c.mkey.into();693				let width = match c.width {694					Width::Star => {695						throw!(CannotUseStarWidthWithObject);696					}697					Width::Fixed(n) => n,698				};699				let precision = match c.precision {700					Some(Width::Star) => {701						throw!(CannotUseStarWidthWithObject);702					}703					Some(Width::Fixed(n)) => Some(n),704					None => None,705				};706707				let value = if c.convtype == ConvTypeV::Percent {708					Val::Null709				} else {710					if f.is_empty() {711						throw!(MappingKeysRequired);712					}713					if let Some(v) = values.get(s.clone(), f.clone())? {714						v715					} else {716						throw!(NoSuchFormatField(f));717					}718				};719720				format_code(s.clone(), &mut out, &value, &c, width, precision)?;721			}722		}723	}724725	Ok(out)726}727728#[cfg(test)]729pub mod test_format {730	use super::*;731732	#[test]733	fn parse() {734		assert_eq!(735			parse_codes(736				"How much error budget is left looking at our %.3f%% availability gurantees?"737			)738			.unwrap()739			.len(),740			4741		);742	}743744	#[test]745	fn octals() {746		let s = State::default();747		assert_eq!(748			format_arr(s.clone(), "%#o", &[Val::Num(8.0)]).unwrap(),749			"010"750		);751		assert_eq!(752			format_arr(s.clone(), "%#4o", &[Val::Num(8.0)]).unwrap(),753			" 010"754		);755		assert_eq!(756			format_arr(s.clone(), "%4o", &[Val::Num(8.0)]).unwrap(),757			"  10"758		);759		assert_eq!(760			format_arr(s.clone(), "%04o", &[Val::Num(8.0)]).unwrap(),761			"0010"762		);763		assert_eq!(764			format_arr(s.clone(), "%+4o", &[Val::Num(8.0)]).unwrap(),765			" +10"766		);767		assert_eq!(768			format_arr(s.clone(), "%+04o", &[Val::Num(8.0)]).unwrap(),769			"+010"770		);771		assert_eq!(772			format_arr(s.clone(), "%-4o", &[Val::Num(8.0)]).unwrap(),773			"10  "774		);775		assert_eq!(776			format_arr(s.clone(), "%+-4o", &[Val::Num(8.0)]).unwrap(),777			"+10 "778		);779		assert_eq!(format_arr(s, "%+-04o", &[Val::Num(8.0)]).unwrap(), "+10 ");780	}781782	#[test]783	fn percent_doesnt_consumes_values() {784		let s = State::default();785		assert_eq!(786			format_arr(787				s,788				"How much error budget is left looking at our %.3f%% availability gurantees?",789				&[Val::Num(4.0)]790			)791			.unwrap(),792			"How much error budget is left looking at our 4.000% availability gurantees?"793		);794	}795}
modifiedcrates/jrsonnet-evaluator/src/stdlib/manifest.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/stdlib/manifest.rs
+++ b/crates/jrsonnet-evaluator/src/stdlib/manifest.rs
@@ -49,7 +49,7 @@
 		}
 		Val::Null => buf.push_str("null"),
 		Val::Str(s) => escape_string_json_buf(s, buf),
-		Val::Num(n) => write!(buf, "{}", n).unwrap(),
+		Val::Num(n) => write!(buf, "{n}").unwrap(),
 		Val::Arr(items) => {
 			buf.push('[');
 			if !items.is_empty() {
modifiedcrates/jrsonnet-evaluator/src/stdlib/mod.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/stdlib/mod.rs
+++ b/crates/jrsonnet-evaluator/src/stdlib/mod.rs
@@ -12,7 +12,7 @@
 pub fn std_format(s: State, str: IStr, vals: Val) -> Result<String> {
 	s.push(
 		CallLocation::native(),
-		|| format!("std.format of {}", str),
+		|| format!("std.format of {str}"),
 		|| {
 			Ok(match vals {
 				Val::Arr(vals) => format_arr(s.clone(), &str, &vals.evaluated(s.clone())?)?,
modifiedcrates/jrsonnet-evaluator/src/trace/mod.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/trace/mod.rs
+++ b/crates/jrsonnet-evaluator/src/trace/mod.rs
@@ -16,12 +16,9 @@
 }
 
 impl PathResolver {
-	/// Will return Self::Relative(cwd), or Self::Absolute on cwd failure
+	/// Will return `Self::Relative(cwd)`, or `Self::Absolute` on cwd failure
 	pub fn new_cwd_fallback() -> Self {
-		match std::env::current_dir() {
-			Ok(v) => Self::Relative(v),
-			Err(_) => Self::Absolute,
-		}
+		std::env::current_dir().map_or(Self::Absolute, Self::Relative)
 	}
 	pub fn resolve(&self, from: &Path) -> String {
 		match self {
@@ -97,10 +94,10 @@
 			use std::fmt::Write;
 
 			writeln!(out)?;
-			let mut n = match path.source_path().path() {
-				Some(r) => self.resolver.resolve(r),
-				None => path.source_path().to_string(),
-			};
+			let mut n = path.source_path().path().map_or_else(
+				|| path.source_path().to_string(),
+				|r| self.resolver.resolve(r),
+			);
 			let mut offset = error.location.offset;
 			let is_eof = if offset >= path.code().len() {
 				offset = path.code().len().saturating_sub(1);
@@ -119,7 +116,7 @@
 
 			write!(n, ":").unwrap();
 			print_code_location(&mut n, &location, &location).unwrap();
-			write!(out, "{:<p$}{}", "", n, p = self.padding,)?;
+			write!(out, "{:<p$}{n}", "", p = self.padding)?;
 		}
 		let file_names = error
 			.trace()
@@ -185,10 +182,10 @@
 			let desc = &item.desc;
 			if let Some(source) = &item.location {
 				let start_end = source.0.map_source_locations(&[source.1, source.2]);
-				let resolved_path = match source.0.source_path().path() {
-					Some(r) => r.display().to_string(),
-					None => source.0.source_path().to_string(),
-				};
+				let resolved_path = source.0.source_path().path().map_or_else(
+					|| source.0.source_path().to_string(),
+					|r| r.display().to_string(),
+				);
 
 				write!(
 					out,
@@ -196,7 +193,7 @@
 					desc, resolved_path, start_end[0].line, start_end[0].column,
 				)?;
 			} else {
-				write!(out, "    during {}", desc)?;
+				write!(out, "    during {desc}")?;
 			}
 		}
 		Ok(())
@@ -252,7 +249,7 @@
 					desc,
 				)?;
 			} else {
-				write!(out, "{}", desc)?;
+				write!(out, "{desc}")?;
 			}
 		}
 		Ok(())
@@ -280,10 +277,10 @@
 			.take(end.line_end_offset - end.line_start_offset)
 			.collect();
 
-		let origin = match origin.source_path().path() {
-			Some(r) => self.resolver.resolve(r),
-			None => origin.source_path().to_string(),
-		};
+		let origin = origin.source_path().path().map_or_else(
+			|| origin.source_path().to_string(),
+			|r| self.resolver.resolve(r),
+		);
 		let snippet = Snippet {
 			opt: FormatOptions {
 				color: true,
@@ -308,7 +305,7 @@
 		};
 
 		let dl = DisplayList::from(snippet);
-		write!(out, "{}", dl)?;
+		write!(out, "{dl}")?;
 
 		Ok(())
 	}
modifiedcrates/jrsonnet-evaluator/src/typed/mod.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/typed/mod.rs
+++ b/crates/jrsonnet-evaluator/src/typed/mod.rs
@@ -21,8 +21,8 @@
 	UnionFailed(ComplexValType, TypeLocErrorList),
 	#[error(
 		"number out of bounds: {0} not in {}..{}",
-		.1.map(|v|v.to_string()).unwrap_or_else(|| "".to_owned()),
-		.2.map(|v|v.to_string()).unwrap_or_else(|| "".to_owned()),
+		.1.map(|v|v.to_string()).unwrap_or_default(),
+		.2.map(|v|v.to_string()).unwrap_or_default(),
 	)]
 	BoundsFailed(f64, Option<f64>, Option<f64>),
 }
@@ -65,7 +65,7 @@
 				writeln!(f)?;
 			}
 			out.clear();
-			write!(out, "{}", err)?;
+			write!(out, "{err}")?;
 
 			for (i, line) in out.lines().enumerate() {
 				if line.trim().is_empty() {
@@ -77,7 +77,7 @@
 					writeln!(f)?;
 					write!(f, "    ")?;
 				}
-				write!(f, "{}", line)?;
+				write!(f, "{line}")?;
 			}
 		}
 		Ok(())
@@ -125,8 +125,8 @@
 impl Display for ValuePathItem {
 	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 		match self {
-			Self::Field(name) => write!(f, ".{:?}", name)?,
-			Self::Index(idx) => write!(f, "[{}]", idx)?,
+			Self::Field(name) => write!(f, ".{name:?}")?,
+			Self::Index(idx) => write!(f, "[{idx}]")?,
 		}
 		Ok(())
 	}
@@ -138,7 +138,7 @@
 	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 		write!(f, "self")?;
 		for elem in self.0.iter().rev() {
-			write!(f, "{}", elem)?;
+			write!(f, "{elem}")?;
 		}
 		Ok(())
 	}
@@ -171,7 +171,7 @@
 					for (i, item) in a.iter(s.clone()).enumerate() {
 						push_type_description(
 							s.clone(),
-							|| format!("array index {}", i),
+							|| format!("array index {i}"),
 							|| ValuePathItem::Index(i as u64),
 							|| elem_type.check(s.clone(), &item.clone()?),
 						)?;
@@ -185,7 +185,7 @@
 					for (i, item) in a.iter(s.clone()).enumerate() {
 						push_type_description(
 							s.clone(),
-							|| format!("array index {}", i),
+							|| format!("array index {i}"),
 							|| ValuePathItem::Index(i as u64),
 							|| elem_type.check(s.clone(), &item.clone()?),
 						)?;
@@ -200,7 +200,7 @@
 						if let Some(got_v) = obj.get(s.clone(), (*k).into())? {
 							push_type_description(
 								s.clone(),
-								|| format!("property {}", k),
+								|| format!("property {k}"),
 								|| ValuePathItem::Field((*k).into()),
 								|| v.check(s.clone(), &got_v),
 							)?;
modifiedcrates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/val.rs
+++ b/crates/jrsonnet-evaluator/src/val.rs
@@ -292,7 +292,7 @@
 				if index >= v.to() {
 					return Ok(None);
 				}
-				v.inner.get(s, index as usize)
+				v.inner.get(s, index)
 			}
 		}
 	}
@@ -332,7 +332,7 @@
 				if index >= s.to() {
 					return None;
 				}
-				s.inner.get_lazy(index as usize)
+				s.inner.get_lazy(index)
 			}
 		}
 	}
@@ -531,8 +531,9 @@
 	}
 }
 
-#[cfg(target_pointer_width = "64")]
-static_assertions::assert_eq_size!(Val, [u8; 32]);
+// Broken between stable and nightly, as there is new layout size optimization
+// #[cfg(target_pointer_width = "64")]
+// static_assertions::assert_eq_size!(Val, [u8; 24]);
 
 impl Val {
 	pub const fn as_bool(&self) -> Option<bool> {
modifiedcrates/jrsonnet-stdlib/src/encoding.rsdiffbeforeafterboth
--- a/crates/jrsonnet-stdlib/src/encoding.rs
+++ b/crates/jrsonnet-stdlib/src/encoding.rs
@@ -28,7 +28,7 @@
 
 #[builtin]
 pub fn builtin_base64_decode_bytes(input: IStr) -> Result<IBytes> {
-	Ok(base64::decode(&input.as_bytes())
+	Ok(base64::decode(input.as_bytes())
 		.map_err(|_| RuntimeError("bad base64".into()))?
 		.as_slice()
 		.into())
@@ -36,6 +36,6 @@
 
 #[builtin]
 pub fn builtin_base64_decode(input: IStr) -> Result<String> {
-	let bytes = base64::decode(&input.as_bytes()).map_err(|_| RuntimeError("bad base64".into()))?;
+	let bytes = base64::decode(input.as_bytes()).map_err(|_| RuntimeError("bad base64".into()))?;
 	Ok(String::from_utf8(bytes).map_err(|_| RuntimeError("bad utf8".into()))?)
 }
modifiedcrates/jrsonnet-stdlib/src/hash.rsdiffbeforeafterboth
--- a/crates/jrsonnet-stdlib/src/hash.rs
+++ b/crates/jrsonnet-stdlib/src/hash.rs
@@ -2,5 +2,5 @@
 
 #[builtin]
 pub fn builtin_md5(str: IStr) -> Result<String> {
-	Ok(format!("{:x}", md5::compute(&str.as_bytes())))
+	Ok(format!("{:x}", md5::compute(str.as_bytes())))
 }
modifiedcrates/jrsonnet-stdlib/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-stdlib/src/lib.rs
+++ b/crates/jrsonnet-stdlib/src/lib.rs
@@ -366,7 +366,7 @@
 
 #[builtin]
 fn builtin_substr(str: IStr, from: usize, len: usize) -> Result<String> {
-	Ok(str.chars().skip(from as usize).take(len as usize).collect())
+	Ok(str.chars().skip(from).take(len).collect())
 }
 
 #[builtin(fields(
@@ -380,7 +380,7 @@
 		.ext_vars
 		.get(&x)
 		.cloned()
-		.ok_or(UndefinedExternalVariable(x))?
+		.ok_or_else(|| UndefinedExternalVariable(x))?
 		.evaluate_arg(s.clone(), ctx, true)?
 		.evaluate(s)?))
 }
@@ -402,7 +402,7 @@
 
 #[builtin]
 fn builtin_char(n: u32) -> Result<char> {
-	Ok(std::char::from_u32(n as u32).ok_or(InvalidUnicodeCodepointGot(n as u32))?)
+	Ok(std::char::from_u32(n).ok_or_else(|| InvalidUnicodeCodepointGot(n))?)
 }
 
 #[builtin(fields(