git.delta.rocks / jrsonnet / refs/commits / 2d0d919b58c4

difftreelog

style fix warnings with nightly clippy

Yaroslav Bolyukin2022-05-26parent: #e1e1d4b.patch.diff
in: master

9 files changed

modifiedcrates/jrsonnet-cli/src/trace.rsdiffbeforeafterboth
--- a/crates/jrsonnet-cli/src/trace.rs
+++ b/crates/jrsonnet-cli/src/trace.rs
@@ -9,7 +9,7 @@
 
 use crate::ConfigureState;
 
-#[derive(PartialEq)]
+#[derive(PartialEq, Eq)]
 pub enum TraceFormatName {
 	Compact,
 	Explaining,
modifiedcrates/jrsonnet-evaluator/src/integrations/serde.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/integrations/serde.rs
+++ b/crates/jrsonnet-evaluator/src/integrations/serde.rs
@@ -13,20 +13,20 @@
 
 	fn into_untyped(value: Self, s: State) -> Result<Val> {
 		Ok(match value {
-			Value::Null => Val::Null,
-			Value::Bool(v) => Val::Bool(v),
-			Value::Number(n) => Val::Num(n.as_f64().ok_or_else(|| {
+			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())
 			})?),
-			Value::String(s) => Val::Str((&s as &str).into()),
-			Value::Array(a) => {
+			Self::String(s) => Val::Str((&s as &str).into()),
+			Self::Array(a) => {
 				let mut out: Vec<Val> = Vec::with_capacity(a.len());
 				for v in a {
 					out.push(Self::into_untyped(v, s.clone())?);
 				}
 				Val::Arr(out.into())
 			}
-			Value::Object(o) => {
+			Self::Object(o) => {
 				let mut builder = ObjValueBuilder::with_capacity(o.len());
 				for (k, v) in o {
 					builder
modifiedcrates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/lib.rs
+++ b/crates/jrsonnet-evaluator/src/lib.rs
@@ -17,6 +17,11 @@
 	clippy::cast_possible_wrap,
 	clippy::cast_possible_truncation,
 	clippy::cast_sign_loss,
+	// False positives
+	// https://github.com/rust-lang/rust-clippy/issues/6902
+	clippy::use_self,
+	// https://github.com/rust-lang/rust-clippy/issues/8539
+	clippy::iter_with_drain,
 )]
 
 // For jrsonnet-macros
modifiedcrates/jrsonnet-evaluator/src/stdlib/format.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/stdlib/format.rs
+++ b/crates/jrsonnet-evaluator/src/stdlib/format.rs
@@ -120,7 +120,7 @@
 	Ok((out, &str[i..]))
 }
 
-#[derive(Debug, PartialEq)]
+#[derive(Debug, PartialEq, Eq)]
 pub enum Width {
 	Star,
 	Fixed(usize),
@@ -174,7 +174,7 @@
 	Ok(((), &str[idx..]))
 }
 
-#[derive(Debug, PartialEq)]
+#[derive(Debug, PartialEq, Eq)]
 pub enum ConvTypeV {
 	Decimal,
 	Octal,
modifiedcrates/jrsonnet-evaluator/src/stdlib/manifest.rsdiffbeforeafterboth
before · crates/jrsonnet-evaluator/src/stdlib/manifest.rs
1use crate::{2	error::{Error::*, Result},3	throw, State, Val,4};56#[derive(PartialEq, Clone, Copy)]7pub enum ManifestType {8	// Applied in manifestification9	Manifest,10	/// Used for std.manifestJson11	/// Empty array/objects extends to "[\n\n]" instead of "[ ]" as in manifest12	Std,13	/// No line breaks, used in `obj+''`14	ToString,15	/// Minified json16	Minify,17}1819pub struct ManifestJsonOptions<'s> {20	pub padding: &'s str,21	pub mtype: ManifestType,22	pub newline: &'s str,23	pub key_val_sep: &'s str,24	#[cfg(feature = "exp-preserve-order")]25	pub preserve_order: bool,26}2728pub fn manifest_json_ex(s: State, val: &Val, options: &ManifestJsonOptions<'_>) -> Result<String> {29	let mut out = String::new();30	manifest_json_ex_buf(s, val, &mut out, &mut String::new(), options)?;31	Ok(out)32}33fn manifest_json_ex_buf(34	s: State,35	val: &Val,36	buf: &mut String,37	cur_padding: &mut String,38	options: &ManifestJsonOptions<'_>,39) -> Result<()> {40	use std::fmt::Write;41	let mtype = options.mtype;42	match val {43		Val::Bool(v) => {44			if *v {45				buf.push_str("true");46			} else {47				buf.push_str("false");48			}49		}50		Val::Null => buf.push_str("null"),51		Val::Str(s) => escape_string_json_buf(s, buf),52		Val::Num(n) => write!(buf, "{}", n).unwrap(),53		Val::Arr(items) => {54			buf.push('[');55			if !items.is_empty() {56				if mtype != ManifestType::ToString && mtype != ManifestType::Minify {57					buf.push_str(options.newline);58				}5960				let old_len = cur_padding.len();61				cur_padding.push_str(options.padding);62				for (i, item) in items.iter(s.clone()).enumerate() {63					if i != 0 {64						buf.push(',');65						if mtype == ManifestType::ToString {66							buf.push(' ');67						} else if mtype != ManifestType::Minify {68							buf.push_str(options.newline);69						}70					}71					buf.push_str(cur_padding);72					manifest_json_ex_buf(s.clone(), &item?, buf, cur_padding, options)?;73				}74				cur_padding.truncate(old_len);7576				if mtype != ManifestType::ToString && mtype != ManifestType::Minify {77					buf.push_str(options.newline);78					buf.push_str(cur_padding);79				}80			} else if mtype == ManifestType::Std {81				buf.push_str("\n\n");82				buf.push_str(cur_padding);83			} else if mtype == ManifestType::ToString || mtype == ManifestType::Manifest {84				buf.push(' ');85			}86			buf.push(']');87		}88		Val::Obj(obj) => {89			obj.run_assertions(s.clone())?;90			buf.push('{');91			let fields = obj.fields(92				#[cfg(feature = "exp-preserve-order")]93				options.preserve_order,94			);95			if !fields.is_empty() {96				if mtype != ManifestType::ToString && mtype != ManifestType::Minify {97					buf.push_str(options.newline);98				}99100				let old_len = cur_padding.len();101				cur_padding.push_str(options.padding);102				for (i, field) in fields.into_iter().enumerate() {103					if i != 0 {104						buf.push(',');105						if mtype == ManifestType::ToString {106							buf.push(' ');107						} else if mtype != ManifestType::Minify {108							buf.push_str(options.newline);109						}110					}111					buf.push_str(cur_padding);112					escape_string_json_buf(&field, buf);113					buf.push_str(options.key_val_sep);114					s.push_description(115						|| format!("field <{}> manifestification", field.clone()),116						|| {117							let value = obj.get(s.clone(), field.clone())?.unwrap();118							manifest_json_ex_buf(s.clone(), &value, buf, cur_padding, options)?;119							Ok(Val::Null)120						},121					)?;122				}123				cur_padding.truncate(old_len);124125				if mtype != ManifestType::ToString && mtype != ManifestType::Minify {126					buf.push_str(options.newline);127					buf.push_str(cur_padding);128				}129			} else if mtype == ManifestType::Std {130				buf.push_str("\n\n");131				buf.push_str(cur_padding);132			} else if mtype == ManifestType::ToString || mtype == ManifestType::Manifest {133				buf.push(' ');134			}135			buf.push('}');136		}137		Val::Func(_) => throw!(RuntimeError("tried to manifest function".into())),138	};139	Ok(())140}141142pub fn escape_string_json(s: &str) -> String {143	let mut buf = String::new();144	escape_string_json_buf(s, &mut buf);145	buf146}147148fn escape_string_json_buf(s: &str, buf: &mut String) {149	use std::fmt::Write;150	buf.push('"');151	for c in s.chars() {152		match c {153			'"' => buf.push_str("\\\""),154			'\\' => buf.push_str("\\\\"),155			'\u{0008}' => buf.push_str("\\b"),156			'\u{000c}' => buf.push_str("\\f"),157			'\n' => buf.push_str("\\n"),158			'\r' => buf.push_str("\\r"),159			'\t' => buf.push_str("\\t"),160			c if c < 32 as char || (c >= 127 as char && c <= 159 as char) => {161				write!(buf, "\\u{:04x}", c as u32).unwrap();162			}163			c => buf.push(c),164		}165	}166	buf.push('"');167}168169pub struct ManifestYamlOptions<'s> {170	/// Padding before fields, i.e171	/// ```yaml172	/// a:173	///   b:174	/// ## <- this175	/// ```176	pub padding: &'s str,177	/// Padding before array elements in objects178	/// ```yaml179	/// a:180	///   - 1181	/// ## <- this182	/// ```183	pub arr_element_padding: &'s str,184	/// Should yaml keys appear unescaped, when possible185	/// ```yaml186	/// "safe_key": 1187	/// # vs188	/// safe_key: 1189	/// ```190	pub quote_keys: bool,191	/// If true - then order of fields is preserved as written,192	/// instead of sorting alphabetically193	#[cfg(feature = "exp-preserve-order")]194	pub preserve_order: bool,195}196197/// From <https://github.com/chyh1990/yaml-rust/blob/da52a68615f2ecdd6b7e4567019f280c433c1521/src/emitter.rs#L289>198/// With added date check199fn yaml_needs_quotes(string: &str) -> bool {200	fn need_quotes_spaces(string: &str) -> bool {201		string.starts_with(' ') || string.ends_with(' ')202	}203204	string.is_empty()205		|| need_quotes_spaces(string)206		|| string.starts_with(|c| matches!(c, '&' | '*' | '?' | '|' | '-' | '<' | '>' | '=' | '!' | '%' | '@'))207		|| string.contains(|c| matches!(c, ':' | '{' | '}' | '[' | ']' | ',' | '#' | '`' | '\"' | '\'' | '\\' | '\0'..='\x06' | '\t' | '\n' | '\r' | '\x0e'..='\x1a' | '\x1c'..='\x1f'))208		|| [209			// http://yaml.org/type/bool.html210			// Note: 'y', 'Y', 'n', 'N', is not quoted deliberately, as in libyaml. PyYAML also parse211			// them as string, not booleans, although it is violating the YAML 1.1 specification.212			// See https://github.com/dtolnay/serde-yaml/pull/83#discussion_r152628088.213			"yes", "Yes", "YES", "no", "No", "NO", "True", "TRUE", "true", "False", "FALSE", "false",214			"on", "On", "ON", "off", "Off", "OFF", // http://yaml.org/type/null.html215			"null", "Null", "NULL", "~",216		].contains(&string)217		|| (string.chars().all(|c| matches!(c, '0'..='9' | '-'))218			&& string.chars().filter(|c| *c == '-').count() == 2)219		|| string.starts_with('.')220		|| string.starts_with("0x")221		|| string.parse::<i64>().is_ok()222		|| string.parse::<f64>().is_ok()223}224225pub fn manifest_yaml_ex(s: State, val: &Val, options: &ManifestYamlOptions<'_>) -> Result<String> {226	let mut out = String::new();227	manifest_yaml_ex_buf(s, val, &mut out, &mut String::new(), options)?;228	Ok(out)229}230231#[allow(clippy::too_many_lines)]232fn manifest_yaml_ex_buf(233	s: State,234	val: &Val,235	buf: &mut String,236	cur_padding: &mut String,237	options: &ManifestYamlOptions<'_>,238) -> Result<()> {239	use std::fmt::Write;240	match val {241		Val::Bool(v) => {242			if *v {243				buf.push_str("true");244			} else {245				buf.push_str("false");246			}247		}248		Val::Null => buf.push_str("null"),249		Val::Str(s) => {250			if s.is_empty() {251				buf.push_str("\"\"");252			} else if let Some(s) = s.strip_suffix('\n') {253				buf.push('|');254				for line in s.split('\n') {255					buf.push('\n');256					buf.push_str(cur_padding);257					buf.push_str(options.padding);258					buf.push_str(line);259				}260			} else if !options.quote_keys && !yaml_needs_quotes(s) {261				buf.push_str(s);262			} else {263				escape_string_json_buf(s, buf);264			}265		}266		Val::Num(n) => write!(buf, "{}", *n).unwrap(),267		Val::Arr(a) => {268			if a.is_empty() {269				buf.push_str("[]");270			} else {271				for (i, item) in a.iter(s.clone()).enumerate() {272					if i != 0 {273						buf.push('\n');274						buf.push_str(cur_padding);275					}276					let item = item?;277					buf.push('-');278					match &item {279						Val::Arr(a) if !a.is_empty() => {280							buf.push('\n');281							buf.push_str(cur_padding);282							buf.push_str(options.padding);283						}284						_ => buf.push(' '),285					}286					let extra_padding = match &item {287						Val::Arr(a) => !a.is_empty(),288						Val::Obj(o) => !o.is_empty(),289						_ => false,290					};291					let prev_len = cur_padding.len();292					if extra_padding {293						cur_padding.push_str(options.padding);294					}295					manifest_yaml_ex_buf(s.clone(), &item, buf, cur_padding, options)?;296					cur_padding.truncate(prev_len);297				}298			}299		}300		Val::Obj(o) => {301			if o.is_empty() {302				buf.push_str("{}");303			} else {304				for (i, key) in o305					.fields(306						#[cfg(feature = "exp-preserve-order")]307						options.preserve_order,308					)309					.iter()310					.enumerate()311				{312					if i != 0 {313						buf.push('\n');314						buf.push_str(cur_padding);315					}316					if !options.quote_keys && !yaml_needs_quotes(key) {317						buf.push_str(key);318					} else {319						escape_string_json_buf(key, buf);320					}321					buf.push(':');322					let prev_len = cur_padding.len();323					let item = o.get(s.clone(), key.clone())?.expect("field exists");324					match &item {325						Val::Arr(a) if !a.is_empty() => {326							buf.push('\n');327							buf.push_str(cur_padding);328							buf.push_str(options.arr_element_padding);329							cur_padding.push_str(options.arr_element_padding);330						}331						Val::Obj(o) if !o.is_empty() => {332							buf.push('\n');333							buf.push_str(cur_padding);334							buf.push_str(options.padding);335							cur_padding.push_str(options.padding);336						}337						_ => buf.push(' '),338					}339					manifest_yaml_ex_buf(s.clone(), &item, buf, cur_padding, options)?;340					cur_padding.truncate(prev_len);341				}342			}343		}344		Val::Func(_) => throw!(RuntimeError("tried to manifest function".into())),345	}346	Ok(())347}
after · crates/jrsonnet-evaluator/src/stdlib/manifest.rs
1use crate::{2	error::{Error::*, Result},3	throw, State, Val,4};56#[derive(PartialEq, Eq, Clone, Copy)]7pub enum ManifestType {8	// Applied in manifestification9	Manifest,10	/// Used for std.manifestJson11	/// Empty array/objects extends to "[\n\n]" instead of "[ ]" as in manifest12	Std,13	/// No line breaks, used in `obj+''`14	ToString,15	/// Minified json16	Minify,17}1819pub struct ManifestJsonOptions<'s> {20	pub padding: &'s str,21	pub mtype: ManifestType,22	pub newline: &'s str,23	pub key_val_sep: &'s str,24	#[cfg(feature = "exp-preserve-order")]25	pub preserve_order: bool,26}2728pub fn manifest_json_ex(s: State, val: &Val, options: &ManifestJsonOptions<'_>) -> Result<String> {29	let mut out = String::new();30	manifest_json_ex_buf(s, val, &mut out, &mut String::new(), options)?;31	Ok(out)32}33fn manifest_json_ex_buf(34	s: State,35	val: &Val,36	buf: &mut String,37	cur_padding: &mut String,38	options: &ManifestJsonOptions<'_>,39) -> Result<()> {40	use std::fmt::Write;41	let mtype = options.mtype;42	match val {43		Val::Bool(v) => {44			if *v {45				buf.push_str("true");46			} else {47				buf.push_str("false");48			}49		}50		Val::Null => buf.push_str("null"),51		Val::Str(s) => escape_string_json_buf(s, buf),52		Val::Num(n) => write!(buf, "{}", n).unwrap(),53		Val::Arr(items) => {54			buf.push('[');55			if !items.is_empty() {56				if mtype != ManifestType::ToString && mtype != ManifestType::Minify {57					buf.push_str(options.newline);58				}5960				let old_len = cur_padding.len();61				cur_padding.push_str(options.padding);62				for (i, item) in items.iter(s.clone()).enumerate() {63					if i != 0 {64						buf.push(',');65						if mtype == ManifestType::ToString {66							buf.push(' ');67						} else if mtype != ManifestType::Minify {68							buf.push_str(options.newline);69						}70					}71					buf.push_str(cur_padding);72					manifest_json_ex_buf(s.clone(), &item?, buf, cur_padding, options)?;73				}74				cur_padding.truncate(old_len);7576				if mtype != ManifestType::ToString && mtype != ManifestType::Minify {77					buf.push_str(options.newline);78					buf.push_str(cur_padding);79				}80			} else if mtype == ManifestType::Std {81				buf.push_str("\n\n");82				buf.push_str(cur_padding);83			} else if mtype == ManifestType::ToString || mtype == ManifestType::Manifest {84				buf.push(' ');85			}86			buf.push(']');87		}88		Val::Obj(obj) => {89			obj.run_assertions(s.clone())?;90			buf.push('{');91			let fields = obj.fields(92				#[cfg(feature = "exp-preserve-order")]93				options.preserve_order,94			);95			if !fields.is_empty() {96				if mtype != ManifestType::ToString && mtype != ManifestType::Minify {97					buf.push_str(options.newline);98				}99100				let old_len = cur_padding.len();101				cur_padding.push_str(options.padding);102				for (i, field) in fields.into_iter().enumerate() {103					if i != 0 {104						buf.push(',');105						if mtype == ManifestType::ToString {106							buf.push(' ');107						} else if mtype != ManifestType::Minify {108							buf.push_str(options.newline);109						}110					}111					buf.push_str(cur_padding);112					escape_string_json_buf(&field, buf);113					buf.push_str(options.key_val_sep);114					s.push_description(115						|| format!("field <{}> manifestification", field.clone()),116						|| {117							let value = obj.get(s.clone(), field.clone())?.unwrap();118							manifest_json_ex_buf(s.clone(), &value, buf, cur_padding, options)?;119							Ok(Val::Null)120						},121					)?;122				}123				cur_padding.truncate(old_len);124125				if mtype != ManifestType::ToString && mtype != ManifestType::Minify {126					buf.push_str(options.newline);127					buf.push_str(cur_padding);128				}129			} else if mtype == ManifestType::Std {130				buf.push_str("\n\n");131				buf.push_str(cur_padding);132			} else if mtype == ManifestType::ToString || mtype == ManifestType::Manifest {133				buf.push(' ');134			}135			buf.push('}');136		}137		Val::Func(_) => throw!(RuntimeError("tried to manifest function".into())),138	};139	Ok(())140}141142pub fn escape_string_json(s: &str) -> String {143	let mut buf = String::new();144	escape_string_json_buf(s, &mut buf);145	buf146}147148fn escape_string_json_buf(s: &str, buf: &mut String) {149	use std::fmt::Write;150	buf.push('"');151	for c in s.chars() {152		match c {153			'"' => buf.push_str("\\\""),154			'\\' => buf.push_str("\\\\"),155			'\u{0008}' => buf.push_str("\\b"),156			'\u{000c}' => buf.push_str("\\f"),157			'\n' => buf.push_str("\\n"),158			'\r' => buf.push_str("\\r"),159			'\t' => buf.push_str("\\t"),160			c if c < 32 as char || (c >= 127 as char && c <= 159 as char) => {161				write!(buf, "\\u{:04x}", c as u32).unwrap();162			}163			c => buf.push(c),164		}165	}166	buf.push('"');167}168169pub struct ManifestYamlOptions<'s> {170	/// Padding before fields, i.e171	/// ```yaml172	/// a:173	///   b:174	/// ## <- this175	/// ```176	pub padding: &'s str,177	/// Padding before array elements in objects178	/// ```yaml179	/// a:180	///   - 1181	/// ## <- this182	/// ```183	pub arr_element_padding: &'s str,184	/// Should yaml keys appear unescaped, when possible185	/// ```yaml186	/// "safe_key": 1187	/// # vs188	/// safe_key: 1189	/// ```190	pub quote_keys: bool,191	/// If true - then order of fields is preserved as written,192	/// instead of sorting alphabetically193	#[cfg(feature = "exp-preserve-order")]194	pub preserve_order: bool,195}196197/// From <https://github.com/chyh1990/yaml-rust/blob/da52a68615f2ecdd6b7e4567019f280c433c1521/src/emitter.rs#L289>198/// With added date check199fn yaml_needs_quotes(string: &str) -> bool {200	fn need_quotes_spaces(string: &str) -> bool {201		string.starts_with(' ') || string.ends_with(' ')202	}203204	string.is_empty()205		|| need_quotes_spaces(string)206		|| string.starts_with(|c| matches!(c, '&' | '*' | '?' | '|' | '-' | '<' | '>' | '=' | '!' | '%' | '@'))207		|| string.contains(|c| matches!(c, ':' | '{' | '}' | '[' | ']' | ',' | '#' | '`' | '\"' | '\'' | '\\' | '\0'..='\x06' | '\t' | '\n' | '\r' | '\x0e'..='\x1a' | '\x1c'..='\x1f'))208		|| [209			// http://yaml.org/type/bool.html210			// Note: 'y', 'Y', 'n', 'N', is not quoted deliberately, as in libyaml. PyYAML also parse211			// them as string, not booleans, although it is violating the YAML 1.1 specification.212			// See https://github.com/dtolnay/serde-yaml/pull/83#discussion_r152628088.213			"yes", "Yes", "YES", "no", "No", "NO", "True", "TRUE", "true", "False", "FALSE", "false",214			"on", "On", "ON", "off", "Off", "OFF", // http://yaml.org/type/null.html215			"null", "Null", "NULL", "~",216		].contains(&string)217		|| (string.chars().all(|c| matches!(c, '0'..='9' | '-'))218			&& string.chars().filter(|c| *c == '-').count() == 2)219		|| string.starts_with('.')220		|| string.starts_with("0x")221		|| string.parse::<i64>().is_ok()222		|| string.parse::<f64>().is_ok()223}224225pub fn manifest_yaml_ex(s: State, val: &Val, options: &ManifestYamlOptions<'_>) -> Result<String> {226	let mut out = String::new();227	manifest_yaml_ex_buf(s, val, &mut out, &mut String::new(), options)?;228	Ok(out)229}230231#[allow(clippy::too_many_lines)]232fn manifest_yaml_ex_buf(233	s: State,234	val: &Val,235	buf: &mut String,236	cur_padding: &mut String,237	options: &ManifestYamlOptions<'_>,238) -> Result<()> {239	use std::fmt::Write;240	match val {241		Val::Bool(v) => {242			if *v {243				buf.push_str("true");244			} else {245				buf.push_str("false");246			}247		}248		Val::Null => buf.push_str("null"),249		Val::Str(s) => {250			if s.is_empty() {251				buf.push_str("\"\"");252			} else if let Some(s) = s.strip_suffix('\n') {253				buf.push('|');254				for line in s.split('\n') {255					buf.push('\n');256					buf.push_str(cur_padding);257					buf.push_str(options.padding);258					buf.push_str(line);259				}260			} else if !options.quote_keys && !yaml_needs_quotes(s) {261				buf.push_str(s);262			} else {263				escape_string_json_buf(s, buf);264			}265		}266		Val::Num(n) => write!(buf, "{}", *n).unwrap(),267		Val::Arr(a) => {268			if a.is_empty() {269				buf.push_str("[]");270			} else {271				for (i, item) in a.iter(s.clone()).enumerate() {272					if i != 0 {273						buf.push('\n');274						buf.push_str(cur_padding);275					}276					let item = item?;277					buf.push('-');278					match &item {279						Val::Arr(a) if !a.is_empty() => {280							buf.push('\n');281							buf.push_str(cur_padding);282							buf.push_str(options.padding);283						}284						_ => buf.push(' '),285					}286					let extra_padding = match &item {287						Val::Arr(a) => !a.is_empty(),288						Val::Obj(o) => !o.is_empty(),289						_ => false,290					};291					let prev_len = cur_padding.len();292					if extra_padding {293						cur_padding.push_str(options.padding);294					}295					manifest_yaml_ex_buf(s.clone(), &item, buf, cur_padding, options)?;296					cur_padding.truncate(prev_len);297				}298			}299		}300		Val::Obj(o) => {301			if o.is_empty() {302				buf.push_str("{}");303			} else {304				for (i, key) in o305					.fields(306						#[cfg(feature = "exp-preserve-order")]307						options.preserve_order,308					)309					.iter()310					.enumerate()311				{312					if i != 0 {313						buf.push('\n');314						buf.push_str(cur_padding);315					}316					if !options.quote_keys && !yaml_needs_quotes(key) {317						buf.push_str(key);318					} else {319						escape_string_json_buf(key, buf);320					}321					buf.push(':');322					let prev_len = cur_padding.len();323					let item = o.get(s.clone(), key.clone())?.expect("field exists");324					match &item {325						Val::Arr(a) if !a.is_empty() => {326							buf.push('\n');327							buf.push_str(cur_padding);328							buf.push_str(options.arr_element_padding);329							cur_padding.push_str(options.arr_element_padding);330						}331						Val::Obj(o) if !o.is_empty() => {332							buf.push('\n');333							buf.push_str(cur_padding);334							buf.push_str(options.padding);335							cur_padding.push_str(options.padding);336						}337						_ => buf.push(' '),338					}339					manifest_yaml_ex_buf(s.clone(), &item, buf, cur_padding, options)?;340					cur_padding.truncate(prev_len);341				}342			}343		}344		Val::Func(_) => throw!(RuntimeError("tried to manifest function".into())),345	}346	Ok(())347}
modifiedcrates/jrsonnet-evaluator/src/trace/location.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/trace/location.rs
+++ b/crates/jrsonnet-evaluator/src/trace/location.rs
@@ -1,5 +1,5 @@
 #[allow(clippy::module_name_repetitions)]
-#[derive(Clone, PartialEq, Debug)]
+#[derive(Clone, PartialEq, Eq, Debug)]
 pub struct CodeLocation {
 	pub offset: usize,
 
modifiedcrates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/val.rs
+++ b/crates/jrsonnet-evaluator/src/val.rs
@@ -476,43 +476,43 @@
 impl Val {
 	pub const fn as_bool(&self) -> Option<bool> {
 		match self {
-			Val::Bool(v) => Some(*v),
+			Self::Bool(v) => Some(*v),
 			_ => None,
 		}
 	}
 	pub const fn as_null(&self) -> Option<()> {
 		match self {
-			Val::Null => Some(()),
+			Self::Null => Some(()),
 			_ => None,
 		}
 	}
 	pub fn as_str(&self) -> Option<IStr> {
 		match self {
-			Val::Str(s) => Some(s.clone()),
+			Self::Str(s) => Some(s.clone()),
 			_ => None,
 		}
 	}
 	pub const fn as_num(&self) -> Option<f64> {
 		match self {
-			Val::Num(n) => Some(*n),
+			Self::Num(n) => Some(*n),
 			_ => None,
 		}
 	}
 	pub fn as_arr(&self) -> Option<ArrValue> {
 		match self {
-			Val::Arr(a) => Some(a.clone()),
+			Self::Arr(a) => Some(a.clone()),
 			_ => None,
 		}
 	}
 	pub fn as_obj(&self) -> Option<ObjValue> {
 		match self {
-			Val::Obj(o) => Some(o.clone()),
+			Self::Obj(o) => Some(o.clone()),
 			_ => None,
 		}
 	}
 	pub fn as_func(&self) -> Option<FuncVal> {
 		match self {
-			Val::Func(f) => Some(f.clone()),
+			Self::Func(f) => Some(f.clone()),
 			_ => None,
 		}
 	}
modifiedcrates/jrsonnet-interner/src/inner.rsdiffbeforeafterboth
--- a/crates/jrsonnet-interner/src/inner.rs
+++ b/crates/jrsonnet-interner/src/inner.rs
@@ -157,7 +157,7 @@
 	pub fn ptr_eq(a: &Self, b: &Self) -> bool {
 		a.0 == b.0
 	}
-	pub fn as_ptr(this: &Self) -> *const u8 {
+	pub const fn as_ptr(this: &Self) -> *const u8 {
 		// SAFETY: data is initialized
 		unsafe { this.0.as_ptr().add(mem::size_of::<InnerHeader>()) }
 	}
modifiedcrates/jrsonnet-parser/src/expr.rsdiffbeforeafterboth
--- a/crates/jrsonnet-parser/src/expr.rs
+++ b/crates/jrsonnet-parser/src/expr.rs
@@ -21,7 +21,7 @@
 }
 
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
-#[derive(Debug, Clone, Copy, PartialEq, Trace)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)]
 pub enum Visibility {
 	/// :
 	Normal,
@@ -60,7 +60,7 @@
 }
 
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
-#[derive(Debug, Clone, Copy, PartialEq, Trace)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)]
 pub enum UnaryOpType {
 	Plus,
 	Minus,
@@ -85,7 +85,7 @@
 }
 
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
-#[derive(Debug, Clone, Copy, PartialEq, Trace)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)]
 pub enum BinaryOpType {
 	Mul,
 	Div,
@@ -179,7 +179,7 @@
 }
 
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
-#[derive(Debug, Clone, PartialEq, Trace)]
+#[derive(Debug, Clone, PartialEq, Eq, Trace)]
 pub enum DestructRest {
 	/// ...rest
 	Keep(IStr),
@@ -188,7 +188,7 @@
 }
 
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
-#[derive(Debug, Clone, PartialEq, Trace)]
+#[derive(Debug, Clone, PartialEq, Eq, Trace)]
 pub enum Destruct {
 	Full(IStr),
 	#[cfg(feature = "exp-destruct")]
@@ -263,7 +263,7 @@
 }
 
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
-#[derive(Debug, PartialEq, Clone, Copy, Trace)]
+#[derive(Debug, PartialEq, Eq, Clone, Copy, Trace)]
 pub enum LiteralType {
 	This,
 	Super,
@@ -357,7 +357,7 @@
 
 /// file, begin offset, end offset
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
-#[derive(Clone, PartialEq, Trace)]
+#[derive(Clone, PartialEq, Eq, Trace)]
 #[skip_trace]
 #[repr(C)]
 pub struct ExprLocation(pub Source, pub u32, pub u32);