git.delta.rocks / jrsonnet / refs/commits / 86c60d81300b

difftreelog

build upgrade to 2021 edition

Yaroslav Bolyukin2022-03-06parent: #9efbcad.patch.diff
in: master

13 files changed

modifiedbindings/jsonnet/Cargo.tomldiffbeforeafterboth
--- a/bindings/jsonnet/Cargo.toml
+++ b/bindings/jsonnet/Cargo.toml
@@ -4,7 +4,7 @@
 version = "0.4.2"
 authors = ["Yaroslav Bolyukin <iam@lach.pw>"]
 license = "MIT"
-edition = "2018"
+edition = "2021"
 publish = false
 
 [dependencies]
modifiedcmds/jrsonnet/Cargo.tomldiffbeforeafterboth
--- a/cmds/jrsonnet/Cargo.toml
+++ b/cmds/jrsonnet/Cargo.toml
@@ -4,8 +4,7 @@
 version = "0.4.2"
 authors = ["Yaroslav Bolyukin <iam@lach.pw>"]
 license = "MIT"
-edition = "2018"
-publish = false
+edition = "2021"
 
 [features]
 # Use mimalloc as allocator
modifiedcrates/jrsonnet-cli/Cargo.tomldiffbeforeafterboth
--- a/crates/jrsonnet-cli/Cargo.toml
+++ b/crates/jrsonnet-cli/Cargo.toml
@@ -4,8 +4,7 @@
 version = "0.4.2"
 authors = ["Yaroslav Bolyukin <iam@lach.pw>"]
 license = "MIT"
-edition = "2018"
-publish = false
+edition = "2021"
 
 [dependencies]
 jrsonnet-evaluator = { path = "../../crates/jrsonnet-evaluator", version = "0.4.2", features = [
modifiedcrates/jrsonnet-evaluator/Cargo.tomldiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/Cargo.toml
+++ b/crates/jrsonnet-evaluator/Cargo.toml
@@ -4,7 +4,7 @@
 version = "0.4.2"
 authors = ["Yaroslav Bolyukin <iam@lach.pw>"]
 license = "MIT"
-edition = "2018"
+edition = "2021"
 
 [features]
 default = ["serialized-stdlib", "explaining-traces"]
modifiedcrates/jrsonnet-evaluator/src/builtin/mod.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/builtin/mod.rs
+++ b/crates/jrsonnet-evaluator/src/builtin/mod.rs
@@ -7,7 +7,7 @@
 	operator::evaluate_mod_op,
 	primitive_equals, push_frame, throw,
 	typed::{Either2, Either4},
-	with_state, ArrValue, Context, FuncVal, IndexableVal, Val,
+	with_state, ArrValue, FuncVal, IndexableVal, Val,
 };
 use crate::{Either, ObjValue};
 use format::{format_arr, format_obj};
modifiedcrates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/lib.rs
+++ b/crates/jrsonnet-evaluator/src/lib.rs
@@ -23,6 +23,8 @@
 pub mod typed;
 mod val;
 
+pub use jrsonnet_parser as parser;
+
 pub use ctx::*;
 pub use dynamic::*;
 use error::{Error::*, LocError, Result, StackTraceElement};
@@ -175,7 +177,7 @@
 pub(crate) fn with_state<T>(f: impl FnOnce(&EvaluationState) -> T) -> T {
 	EVAL_STATE.with(|s| f(s.borrow().as_ref().unwrap()))
 }
-pub(crate) fn push_frame<T>(
+pub fn push_frame<T>(
 	e: Option<&ExprLocation>,
 	frame_desc: impl FnOnce() -> String,
 	f: impl FnOnce() -> Result<T>,
@@ -184,7 +186,7 @@
 }
 
 #[allow(dead_code)]
-pub(crate) fn push_val_frame(
+pub fn push_val_frame(
 	e: &ExprLocation,
 	frame_desc: impl FnOnce() -> String,
 	f: impl FnOnce() -> Result<Val>,
@@ -192,7 +194,7 @@
 	with_state(|s| s.push_val(e, frame_desc, f))
 }
 #[allow(dead_code)]
-pub(crate) fn push_description_frame<T>(
+pub fn push_description_frame<T>(
 	frame_desc: impl FnOnce() -> String,
 	f: impl FnOnce() -> Result<T>,
 ) -> Result<T> {
modifiedcrates/jrsonnet-evaluator/src/typed/mod.rsdiffbeforeafterboth
before · crates/jrsonnet-evaluator/src/typed/mod.rs
1use std::{fmt::Display, rc::Rc};23mod conversions;4pub use conversions::*;56use crate::{7	error::{Error, LocError, Result},8	push_description_frame, Val,9};10use gcmodule::Trace;11use jrsonnet_types::{ComplexValType, ValType};12use thiserror::Error;1314#[macro_export]15macro_rules! unwrap_type {16	($desc: expr, $value: expr, $typ: expr => $match: path) => {{17		use $crate::{push_stack_frame, typed::CheckType};18		push_stack_frame(None, $desc, || Ok($typ.check(&$value)?))?;19		match $value {20			$match(v) => v,21			_ => unreachable!(),22		}23	}};24}2526#[derive(Debug, Error, Clone, Trace)]27pub enum TypeError {28	#[error("expected {0}, got {1}")]29	ExpectedGot(ComplexValType, ValType),30	#[error("missing property {0} from {1:?}")]31	MissingProperty(#[skip_trace] Rc<str>, ComplexValType),32	#[error("every failed from {0}:\n{1}")]33	UnionFailed(ComplexValType, TypeLocErrorList),34	#[error(35		"number out of bounds: {0} not in {}..{}",36		.1.map(|v|v.to_string()).unwrap_or_else(|| "".to_owned()),37		.2.map(|v|v.to_string()).unwrap_or_else(|| "".to_owned()),38	)]39	BoundsFailed(f64, Option<f64>, Option<f64>),40}41impl From<TypeError> for LocError {42	fn from(e: TypeError) -> Self {43		Error::TypeError(e.into()).into()44	}45}4647#[derive(Debug, Clone, Trace)]48pub struct TypeLocError(Box<TypeError>, ValuePathStack);49impl From<TypeError> for TypeLocError {50	fn from(e: TypeError) -> Self {51		Self(Box::new(e), ValuePathStack(Vec::new()))52	}53}54impl From<TypeLocError> for LocError {55	fn from(e: TypeLocError) -> Self {56		Error::TypeError(e).into()57	}58}59impl Display for TypeLocError {60	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {61		write!(f, "{}", self.0)?;62		if !(self.1).0.is_empty() {63			write!(f, " at {}", self.1)?;64		}65		Ok(())66	}67}6869#[derive(Debug, Clone, Trace)]70pub struct TypeLocErrorList(Vec<TypeLocError>);71impl Display for TypeLocErrorList {72	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {73		use std::fmt::Write;74		let mut out = String::new();75		for (i, err) in self.0.iter().enumerate() {76			if i != 0 {77				writeln!(f)?;78			}79			out.clear();80			write!(out, "{}", err)?;8182			for (i, line) in out.lines().enumerate() {83				if line.trim().is_empty() {84					continue;85				}86				if i != 0 {87					writeln!(f)?;88					write!(f, "    ")?;89				} else {90					write!(f, "  - ")?;91				}92				write!(f, "{}", line)?;93			}94		}95		Ok(())96	}97}9899fn push_type_description(100	error_reason: impl Fn() -> String,101	path: impl Fn() -> ValuePathItem,102	item: impl Fn() -> Result<()>,103) -> Result<()> {104	push_description_frame(error_reason, || match item() {105		Ok(_) => Ok(()),106		Err(mut e) => {107			if let Error::TypeError(e) = &mut e.error_mut() {108				(e.1).0.push(path())109			}110			Err(e)111		}112	})113}114115// TODO: check_fast for fast path of union type checking116pub trait CheckType {117	fn check(&self, value: &Val) -> Result<()>;118}119120impl CheckType for ValType {121	fn check(&self, value: &Val) -> Result<()> {122		let got = value.value_type();123		if got != *self {124			let loc_error: TypeLocError = TypeError::ExpectedGot((*self).into(), got).into();125			return Err(loc_error.into());126		}127		Ok(())128	}129}130131#[derive(Clone, Debug, Trace)]132enum ValuePathItem {133	Field(#[skip_trace] Rc<str>),134	Index(u64),135}136impl Display for ValuePathItem {137	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {138		match self {139			Self::Field(name) => write!(f, ".{}", name)?,140			Self::Index(idx) => write!(f, "[{}]", idx)?,141		}142		Ok(())143	}144}145146#[derive(Clone, Debug, Trace)]147struct ValuePathStack(Vec<ValuePathItem>);148impl Display for ValuePathStack {149	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {150		write!(f, "self")?;151		for elem in self.0.iter().rev() {152			write!(f, "{}", elem)?;153		}154		Ok(())155	}156}157158impl CheckType for ComplexValType {159	fn check(&self, value: &Val) -> Result<()> {160		match self {161			Self::Any => Ok(()),162			Self::Simple(s) => s.check(value),163			Self::Char => match value {164				Val::Str(s) if s.len() == 1 || s.chars().count() == 1 => Ok(()),165				v => Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),166			},167			Self::BoundedNumber(from, to) => {168				if let Val::Num(n) = value {169					if from.map(|from| from > *n).unwrap_or(false)170						|| to.map(|to| to < *n).unwrap_or(false)171					{172						return Err(TypeError::BoundsFailed(*n, *from, *to).into());173					}174					Ok(())175				} else {176					Err(TypeError::ExpectedGot(self.clone(), value.value_type()).into())177				}178			}179			Self::Array(elem_type) => match value {180				Val::Arr(a) => {181					for (i, item) in a.iter().enumerate() {182						push_type_description(183							|| format!("array index {}", i),184							|| ValuePathItem::Index(i as u64),185							|| elem_type.check(&item.clone()?),186						)?;187					}188					Ok(())189				}190				v => Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),191			},192			Self::ArrayRef(elem_type) => match value {193				Val::Arr(a) => {194					for (i, item) in a.iter().enumerate() {195						push_type_description(196							|| format!("array index {}", i),197							|| ValuePathItem::Index(i as u64),198							|| elem_type.check(&item.clone()?),199						)?;200					}201					Ok(())202				}203				v => Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),204			},205			Self::ObjectRef(elems) => match value {206				Val::Obj(obj) => {207					for (k, v) in elems.iter() {208						if let Some(got_v) = obj.get((*k).into())? {209							push_type_description(210								|| format!("property {}", k),211								|| ValuePathItem::Field((*k).into()),212								|| v.check(&got_v),213							)?214						} else {215							return Err(216								TypeError::MissingProperty((*k).into(), self.clone()).into()217							);218						}219					}220					Ok(())221				}222				v => Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),223			},224			Self::Union(types) => {225				let mut errors = Vec::new();226				for ty in types.iter() {227					match ty.check(value) {228						Ok(()) => {229							return Ok(());230						}231						Err(e) => match e.error() {232							Error::TypeError(e) => errors.push(e.clone()),233							_ => return Err(e),234						},235					}236				}237				Err(TypeError::UnionFailed(self.clone(), TypeLocErrorList(errors)).into())238			}239			Self::UnionRef(types) => {240				let mut errors = Vec::new();241				for ty in types.iter() {242					match ty.check(value) {243						Ok(()) => {244							return Ok(());245						}246						Err(e) => match e.error() {247							Error::TypeError(e) => errors.push(e.clone()),248							_ => return Err(e),249						},250					}251				}252				Err(TypeError::UnionFailed(self.clone(), TypeLocErrorList(errors)).into())253			}254			Self::Sum(types) => {255				for ty in types.iter() {256					ty.check(value)?257				}258				Ok(())259			}260			Self::SumRef(types) => {261				for ty in types.iter() {262					ty.check(value)?263				}264				Ok(())265			}266		}267	}268}
after · crates/jrsonnet-evaluator/src/typed/mod.rs
1use std::{fmt::Display, rc::Rc};23mod conversions;4pub use conversions::*;56use crate::{7	error::{Error, LocError, Result},8	push_description_frame, Val,9};10use gcmodule::Trace;11use jrsonnet_types::{ComplexValType, ValType};12use thiserror::Error;1314#[macro_export]15macro_rules! unwrap_type {16	($desc:expr, $value:expr, $typ:expr => $match:path) => {{17		use $crate::{push_frame, typed::CheckType};18		push_frame(None, $desc, || Ok($typ.check(&$value)?))?;19		match $value {20			$match(v) => v,21			_ => unreachable!(),22		}23	}};24}2526#[derive(Debug, Error, Clone, Trace)]27pub enum TypeError {28	#[error("expected {0}, got {1}")]29	ExpectedGot(ComplexValType, ValType),30	#[error("missing property {0} from {1:?}")]31	MissingProperty(#[skip_trace] Rc<str>, ComplexValType),32	#[error("every failed from {0}:\n{1}")]33	UnionFailed(ComplexValType, TypeLocErrorList),34	#[error(35		"number out of bounds: {0} not in {}..{}",36		.1.map(|v|v.to_string()).unwrap_or_else(|| "".to_owned()),37		.2.map(|v|v.to_string()).unwrap_or_else(|| "".to_owned()),38	)]39	BoundsFailed(f64, Option<f64>, Option<f64>),40}41impl From<TypeError> for LocError {42	fn from(e: TypeError) -> Self {43		Error::TypeError(e.into()).into()44	}45}4647#[derive(Debug, Clone, Trace)]48pub struct TypeLocError(Box<TypeError>, ValuePathStack);49impl From<TypeError> for TypeLocError {50	fn from(e: TypeError) -> Self {51		Self(Box::new(e), ValuePathStack(Vec::new()))52	}53}54impl From<TypeLocError> for LocError {55	fn from(e: TypeLocError) -> Self {56		Error::TypeError(e).into()57	}58}59impl Display for TypeLocError {60	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {61		write!(f, "{}", self.0)?;62		if !(self.1).0.is_empty() {63			write!(f, " at {}", self.1)?;64		}65		Ok(())66	}67}6869#[derive(Debug, Clone, Trace)]70pub struct TypeLocErrorList(Vec<TypeLocError>);71impl Display for TypeLocErrorList {72	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {73		use std::fmt::Write;74		let mut out = String::new();75		for (i, err) in self.0.iter().enumerate() {76			if i != 0 {77				writeln!(f)?;78			}79			out.clear();80			write!(out, "{}", err)?;8182			for (i, line) in out.lines().enumerate() {83				if line.trim().is_empty() {84					continue;85				}86				if i != 0 {87					writeln!(f)?;88					write!(f, "    ")?;89				} else {90					write!(f, "  - ")?;91				}92				write!(f, "{}", line)?;93			}94		}95		Ok(())96	}97}9899fn push_type_description(100	error_reason: impl Fn() -> String,101	path: impl Fn() -> ValuePathItem,102	item: impl Fn() -> Result<()>,103) -> Result<()> {104	push_description_frame(error_reason, || match item() {105		Ok(_) => Ok(()),106		Err(mut e) => {107			if let Error::TypeError(e) = &mut e.error_mut() {108				(e.1).0.push(path())109			}110			Err(e)111		}112	})113}114115// TODO: check_fast for fast path of union type checking116pub trait CheckType {117	fn check(&self, value: &Val) -> Result<()>;118}119120impl CheckType for ValType {121	fn check(&self, value: &Val) -> Result<()> {122		let got = value.value_type();123		if got != *self {124			let loc_error: TypeLocError = TypeError::ExpectedGot((*self).into(), got).into();125			return Err(loc_error.into());126		}127		Ok(())128	}129}130131#[derive(Clone, Debug, Trace)]132enum ValuePathItem {133	Field(#[skip_trace] Rc<str>),134	Index(u64),135}136impl Display for ValuePathItem {137	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {138		match self {139			Self::Field(name) => write!(f, ".{}", name)?,140			Self::Index(idx) => write!(f, "[{}]", idx)?,141		}142		Ok(())143	}144}145146#[derive(Clone, Debug, Trace)]147struct ValuePathStack(Vec<ValuePathItem>);148impl Display for ValuePathStack {149	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {150		write!(f, "self")?;151		for elem in self.0.iter().rev() {152			write!(f, "{}", elem)?;153		}154		Ok(())155	}156}157158impl CheckType for ComplexValType {159	fn check(&self, value: &Val) -> Result<()> {160		match self {161			Self::Any => Ok(()),162			Self::Simple(s) => s.check(value),163			Self::Char => match value {164				Val::Str(s) if s.len() == 1 || s.chars().count() == 1 => Ok(()),165				v => Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),166			},167			Self::BoundedNumber(from, to) => {168				if let Val::Num(n) = value {169					if from.map(|from| from > *n).unwrap_or(false)170						|| to.map(|to| to < *n).unwrap_or(false)171					{172						return Err(TypeError::BoundsFailed(*n, *from, *to).into());173					}174					Ok(())175				} else {176					Err(TypeError::ExpectedGot(self.clone(), value.value_type()).into())177				}178			}179			Self::Array(elem_type) => match value {180				Val::Arr(a) => {181					for (i, item) in a.iter().enumerate() {182						push_type_description(183							|| format!("array index {}", i),184							|| ValuePathItem::Index(i as u64),185							|| elem_type.check(&item.clone()?),186						)?;187					}188					Ok(())189				}190				v => Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),191			},192			Self::ArrayRef(elem_type) => match value {193				Val::Arr(a) => {194					for (i, item) in a.iter().enumerate() {195						push_type_description(196							|| format!("array index {}", i),197							|| ValuePathItem::Index(i as u64),198							|| elem_type.check(&item.clone()?),199						)?;200					}201					Ok(())202				}203				v => Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),204			},205			Self::ObjectRef(elems) => match value {206				Val::Obj(obj) => {207					for (k, v) in elems.iter() {208						if let Some(got_v) = obj.get((*k).into())? {209							push_type_description(210								|| format!("property {}", k),211								|| ValuePathItem::Field((*k).into()),212								|| v.check(&got_v),213							)?214						} else {215							return Err(216								TypeError::MissingProperty((*k).into(), self.clone()).into()217							);218						}219					}220					Ok(())221				}222				v => Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),223			},224			Self::Union(types) => {225				let mut errors = Vec::new();226				for ty in types.iter() {227					match ty.check(value) {228						Ok(()) => {229							return Ok(());230						}231						Err(e) => match e.error() {232							Error::TypeError(e) => errors.push(e.clone()),233							_ => return Err(e),234						},235					}236				}237				Err(TypeError::UnionFailed(self.clone(), TypeLocErrorList(errors)).into())238			}239			Self::UnionRef(types) => {240				let mut errors = Vec::new();241				for ty in types.iter() {242					match ty.check(value) {243						Ok(()) => {244							return Ok(());245						}246						Err(e) => match e.error() {247							Error::TypeError(e) => errors.push(e.clone()),248							_ => return Err(e),249						},250					}251				}252				Err(TypeError::UnionFailed(self.clone(), TypeLocErrorList(errors)).into())253			}254			Self::Sum(types) => {255				for ty in types.iter() {256					ty.check(value)?257				}258				Ok(())259			}260			Self::SumRef(types) => {261				for ty in types.iter() {262					ty.check(value)?263				}264				Ok(())265			}266		}267	}268}
modifiedcrates/jrsonnet-interner/Cargo.tomldiffbeforeafterboth
--- a/crates/jrsonnet-interner/Cargo.toml
+++ b/crates/jrsonnet-interner/Cargo.toml
@@ -4,7 +4,7 @@
 version = "0.4.2"
 authors = ["Yaroslav Bolyukin <iam@lach.pw>"]
 license = "MIT"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
 serde = { version = "1.0" }
modifiedcrates/jrsonnet-macros/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-macros/src/lib.rs
+++ b/crates/jrsonnet-macros/src/lib.rs
@@ -136,7 +136,11 @@
 		#[derive(Clone, Copy, gcmodule::Trace)]
 		#vis struct #name {}
 		const _: () = {
-			use ::jrsonnet_evaluator::function::{Builtin, StaticBuiltin, BuiltinParam, ArgsLike};
+			use ::jrsonnet_evaluator::{
+				function::{Builtin, StaticBuiltin, BuiltinParam, ArgsLike, parse_builtin_call},
+				error::Result, Context,
+				parser::ExprLocation,
+			};
 			const PARAMS: &'static [BuiltinParam] = &[
 				#(#params),*
 			];
@@ -156,7 +160,7 @@
 					PARAMS
 				}
 				fn call(&self, context: Context, loc: Option<&ExprLocation>, args: &dyn ArgsLike) -> Result<Val> {
-					let parsed = ::jrsonnet_evaluator::function::parse_builtin_call(context, &PARAMS, args, false)?;
+					let parsed = parse_builtin_call(context, &PARAMS, args, false)?;
 
 					let result: #result = #name(#(#args),*);
 					let result = result?;
modifiedcrates/jrsonnet-parser/Cargo.tomldiffbeforeafterboth
--- a/crates/jrsonnet-parser/Cargo.toml
+++ b/crates/jrsonnet-parser/Cargo.toml
@@ -4,7 +4,7 @@
 version = "0.4.2"
 authors = ["Yaroslav Bolyukin <iam@lach.pw>"]
 license = "MIT"
-edition = "2018"
+edition = "2021"
 
 [features]
 default = []
@@ -14,7 +14,7 @@
 [dependencies]
 jrsonnet-interner = { path = "../jrsonnet-interner", version = "0.4.2" }
 
-peg = "0.7.0"
+peg = "0.8.0"
 
 serde = { version = "1.0", features = ["derive", "rc"], optional = true }
 gcmodule = { git = "https://github.com/CertainLach/gcmodule", branch = "jrsonnet" }
modifiedcrates/jrsonnet-parser/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-parser/src/lib.rs
+++ b/crates/jrsonnet-parser/src/lib.rs
@@ -114,8 +114,8 @@
 			/ "\\x" hex_char() hex_char()
 			/ ['\\'] (quiet! { ['b' | 'f' | 'n' | 'r' | 't'] / c() } / expected!("<escape character>"))
 		pub rule string() -> String
-			= ['"'] str:$(string_char(<['"']>)*) ['"'] {? unescape::unescape(str).ok_or("<escaped string>")}
-			/ ['\''] str:$(string_char(<['\'']>)*) ['\''] {? unescape::unescape(str).ok_or("<escaped string>")}
+			= ['"'] str:$(string_char(<"\"">)*) ['"'] {? unescape::unescape(str).ok_or("<escaped string>")}
+			/ ['\''] str:$(string_char(<"\'">)*) ['\''] {? unescape::unescape(str).ok_or("<escaped string>")}
 			/ quiet!{ "@'" str:$(("''" / (!['\''][_]))*) "'" {str.replace("''", "'")}
 			/ "@\"" str:$(("\"\"" / (!['"'][_]))*) "\"" {str.replace("\"\"", "\"")}
 			/ string_block() } / expected!("<string>")
modifiedcrates/jrsonnet-stdlib/Cargo.tomldiffbeforeafterboth
--- a/crates/jrsonnet-stdlib/Cargo.toml
+++ b/crates/jrsonnet-stdlib/Cargo.toml
@@ -4,7 +4,7 @@
 version = "0.4.2"
 authors = ["Yaroslav Bolyukin <iam@lach.pw>"]
 license = "MIT"
-edition = "2018"
+edition = "2021"
 
 [features]
 
modifiedcrates/jrsonnet-types/Cargo.tomldiffbeforeafterboth
--- a/crates/jrsonnet-types/Cargo.toml
+++ b/crates/jrsonnet-types/Cargo.toml
@@ -4,8 +4,8 @@
 version = "0.4.2"
 authors = ["Yaroslav Bolyukin <iam@lach.pw>"]
 license = "MIT"
-edition = "2018"
+edition = "2021"
 
 [dependencies]
-peg = "0.7.0"
+peg = "0.8.0"
 gcmodule = { git = "https://github.com/CertainLach/gcmodule", branch = "jrsonnet" }