difftreelog
refactor unify throw & throw_runtime
in: master
13 files changed
crates/jrsonnet-evaluator/src/error.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/error.rs
+++ b/crates/jrsonnet-evaluator/src/error.rs
@@ -266,14 +266,13 @@
#[macro_export]
macro_rules! throw {
- ($e: expr) => {
- return Err($e.into())
+ ($w:ident$(::$i:ident)*$(($($tt:tt)*))?) => {
+ return Err($w$(::$i)*$(($($tt)*))?.into())
};
-}
-
-#[macro_export]
-macro_rules! throw_runtime {
- ($($tt:tt)*) => {
- return Err($crate::error::Error::RuntimeError(format!($($tt)*).into()).into())
+ ($l:literal) => {
+ return Err($crate::error::Error::RuntimeError($l.into()).into())
+ };
+ ($l:literal, $($tt:tt)*) => {
+ return Err($crate::error::Error::RuntimeError(format!($l, $($tt)*).into()).into())
};
}
crates/jrsonnet-evaluator/src/evaluate/destructure.rsdiffbeforeafterboth1use jrsonnet_gcmodule::Trace;2use jrsonnet_interner::IStr;3use jrsonnet_parser::{BindSpec, Destruct, LocExpr, ParamsDesc};45use crate::{6 error::{Error::*, Result},7 evaluate, evaluate_method, evaluate_named,8 gc::GcHashMap,9 tb, throw,10 val::ThunkValue,11 Context, Pending, State, Thunk, Val,12};1314#[allow(clippy::too_many_lines)]15#[allow(unused_variables)]16pub fn destruct(17 d: &Destruct,18 parent: Thunk<Val>,19 fctx: Pending<Context>,20 new_bindings: &mut GcHashMap<IStr, Thunk<Val>>,21) -> Result<()> {22 match d {23 Destruct::Full(v) => {24 let old = new_bindings.insert(v.clone(), parent);25 if old.is_some() {26 throw!(DuplicateLocalVar(v.clone()))27 }28 }29 #[cfg(feature = "exp-destruct")]30 Destruct::Skip => {}31 #[cfg(feature = "exp-destruct")]32 Destruct::Array { start, rest, end } => {33 use jrsonnet_parser::DestructRest;3435 use crate::{throw_runtime, val::ArrValue};3637 #[derive(Trace)]38 struct DataThunk {39 parent: Thunk<Val>,40 min_len: usize,41 has_rest: bool,42 }43 impl ThunkValue for DataThunk {44 type Output = ArrValue;4546 fn get(self: Box<Self>, s: State) -> Result<Self::Output> {47 let v = self.parent.evaluate(s)?;48 let arr = match v {49 Val::Arr(a) => a,50 _ => throw_runtime!("expected array"),51 };52 if !self.has_rest {53 if arr.len() != self.min_len {54 throw_runtime!("expected {} elements, got {}", self.min_len, arr.len())55 }56 } else if arr.len() < self.min_len {57 throw_runtime!(58 "expected at least {} elements, but array was only {}",59 self.min_len,60 arr.len()61 )62 }63 Ok(arr)64 }65 }6667 let full = Thunk::new(tb!(DataThunk {68 min_len: start.len() + end.len(),69 has_rest: rest.is_some(),70 parent,71 }));7273 {74 #[derive(Trace)]75 struct BaseThunk {76 full: Thunk<ArrValue>,77 index: usize,78 }79 impl ThunkValue for BaseThunk {80 type Output = Val;8182 fn get(self: Box<Self>, s: State) -> Result<Self::Output> {83 let full = self.full.evaluate(s.clone())?;84 Ok(full.get(s, self.index)?.expect("length is checked"))85 }86 }87 for (i, d) in start.iter().enumerate() {88 destruct(89 d,90 Thunk::new(tb!(BaseThunk {91 full: full.clone(),92 index: i,93 })),94 fctx.clone(),95 new_bindings,96 )?;97 }98 }99100 match rest {101 Some(DestructRest::Keep(v)) => {102 #[derive(Trace)]103 struct RestThunk {104 full: Thunk<ArrValue>,105 start: usize,106 end: usize,107 }108 impl ThunkValue for RestThunk {109 type Output = Val;110111 fn get(self: Box<Self>, s: State) -> Result<Self::Output> {112 let full = self.full.evaluate(s)?;113 let to = full.len() - self.end;114 Ok(Val::Arr(full.slice(Some(self.start), Some(to), None)))115 }116 }117118 destruct(119 &Destruct::Full(v.clone()),120 Thunk::new(tb!(RestThunk {121 full: full.clone(),122 start: start.len(),123 end: end.len(),124 })),125 fctx.clone(),126 new_bindings,127 )?;128 }129 Some(DestructRest::Drop) => {}130 None => {}131 }132133 {134 #[derive(Trace)]135 struct EndThunk {136 full: Thunk<ArrValue>,137 index: usize,138 end: usize,139 }140 impl ThunkValue for EndThunk {141 type Output = Val;142143 fn get(self: Box<Self>, s: State) -> Result<Self::Output> {144 let full = self.full.evaluate(s.clone())?;145 Ok(full146 .get(s, full.len() - self.end + self.index)?147 .expect("length is checked"))148 }149 }150 for (i, d) in end.iter().enumerate() {151 destruct(152 d,153 Thunk::new(tb!(EndThunk {154 full: full.clone(),155 index: i,156 end: end.len(),157 })),158 fctx.clone(),159 new_bindings,160 )?;161 }162 }163 }164 #[cfg(feature = "exp-destruct")]165 Destruct::Object { fields, rest } => {166 use crate::{obj::ObjValue, throw_runtime};167168 #[derive(Trace)]169 struct DataThunk {170 parent: Thunk<Val>,171 field_names: Vec<IStr>,172 has_rest: bool,173 }174 impl ThunkValue for DataThunk {175 type Output = ObjValue;176177 fn get(self: Box<Self>, s: State) -> Result<Self::Output> {178 let v = self.parent.evaluate(s)?;179 let obj = match v {180 Val::Obj(o) => o,181 _ => throw_runtime!("expected object"),182 };183 for field in &self.field_names {184 if !obj.has_field_ex(field.clone(), true) {185 throw_runtime!("missing field: {}", field);186 }187 }188 if !self.has_rest {189 let len = obj.len();190 if len != self.field_names.len() {191 throw_runtime!("too many fields, and rest not found");192 }193 }194 Ok(obj)195 }196 }197 let field_names: Vec<_> = fields198 .iter()199 .filter(|f| f.2.is_none())200 .map(|f| f.0.clone())201 .collect();202 let full = Thunk::new(tb!(DataThunk {203 parent,204 field_names: field_names.clone(),205 has_rest: rest.is_some()206 }));207208 for (field, d, default) in fields {209 #[derive(Trace)]210 struct FieldThunk {211 full: Thunk<ObjValue>,212 field: IStr,213 default: Option<(Pending<Context>, LocExpr)>,214 }215 impl ThunkValue for FieldThunk {216 type Output = Val;217218 fn get(self: Box<Self>, s: State) -> Result<Self::Output> {219 let full = self.full.evaluate(s.clone())?;220 if let Some(field) = full.get(s.clone(), self.field)? {221 Ok(field)222 } else {223 let (fctx, expr) = self.default.as_ref().expect("shape is checked");224 Ok(evaluate(s, fctx.clone().unwrap(), &expr)?)225 }226 }227 }228 let value = Thunk::new(tb!(FieldThunk {229 full: full.clone(),230 field: field.clone(),231 default: default.clone().map(|e| (fctx.clone(), e)),232 }));233 if let Some(d) = d {234 destruct(d, value, fctx.clone(), new_bindings)?;235 } else {236 destruct(237 &Destruct::Full(field.clone()),238 value,239 fctx.clone(),240 new_bindings,241 )?;242 }243 }244 }245 }246 Ok(())247}248249pub fn evaluate_dest(250 d: &BindSpec,251 fctx: Pending<Context>,252 new_bindings: &mut GcHashMap<IStr, Thunk<Val>>,253) -> Result<()> {254 match d {255 BindSpec::Field { into, value } => {256 #[derive(Trace)]257 struct EvaluateThunkValue {258 name: Option<IStr>,259 fctx: Pending<Context>,260 expr: LocExpr,261 }262 impl ThunkValue for EvaluateThunkValue {263 type Output = Val;264 fn get(self: Box<Self>, s: State) -> Result<Self::Output> {265 if let Some(name) = self.name {266 evaluate_named(s, self.fctx.unwrap(), &self.expr, name)267 } else {268 evaluate(s, self.fctx.unwrap(), &self.expr)269 }270 }271 }272 let data = Thunk::new(tb!(EvaluateThunkValue {273 name: into.name(),274 fctx: fctx.clone(),275 expr: value.clone(),276 }));277 destruct(into, data, fctx, new_bindings)?;278 }279 BindSpec::Function {280 name,281 params,282 value,283 } => {284 #[derive(Trace)]285 struct MethodThunk {286 fctx: Pending<Context>,287 name: IStr,288 params: ParamsDesc,289 value: LocExpr,290 }291 impl ThunkValue for MethodThunk {292 type Output = Val;293294 fn get(self: Box<Self>, _s: State) -> Result<Self::Output> {295 Ok(evaluate_method(296 self.fctx.unwrap(),297 self.name,298 self.params,299 self.value,300 ))301 }302 }303304 let old = new_bindings.insert(305 name.clone(),306 Thunk::new(tb!(MethodThunk {307 fctx,308 name: name.clone(),309 params: params.clone(),310 value: value.clone()311 })),312 );313 if old.is_some() {314 throw!(DuplicateLocalVar(name.clone()))315 }316 }317 }318 Ok(())319}crates/jrsonnet-evaluator/src/evaluate/operator.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/evaluate/operator.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/operator.rs
@@ -150,13 +150,13 @@
(Num(v1), BitXor, Num(v2)) => Num(f64::from((*v1 as i32) ^ (*v2 as i32))),
(Num(v1), Lhs, Num(v2)) => {
if *v2 < 0.0 {
- throw!(RuntimeError("shift by negative exponent".into()))
+ throw!("shift by negative exponent")
}
Num(f64::from((*v1 as i32) << (*v2 as i32)))
}
(Num(v1), Rhs, Num(v2)) => {
if *v2 < 0.0 {
- throw!(RuntimeError("shift by negative exponent".into()))
+ throw!("shift by negative exponent")
}
Num(f64::from((*v1 as i32) >> (*v2 as i32)))
}
crates/jrsonnet-evaluator/src/integrations/serde.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/integrations/serde.rs
+++ b/crates/jrsonnet-evaluator/src/integrations/serde.rs
@@ -72,7 +72,7 @@
}
Self::Object(out)
}
- Val::Func(_) => throw!(RuntimeError("tried to manifest function".into())),
+ Val::Func(_) => throw!("tried to manifest function"),
})
}
}
crates/jrsonnet-evaluator/src/stdlib/format.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/stdlib/format.rs
+++ b/crates/jrsonnet-evaluator/src/stdlib/format.rs
@@ -591,9 +591,7 @@
),
Val::Str(s) => {
if s.chars().count() != 1 {
- throw!(RuntimeError(
- format!("%c expected 1 char string, got {}", s.chars().count()).into(),
- ));
+ throw!("%c expected 1 char string, got {}", s.chars().count(),);
}
tmp_out.push_str(&s);
}
crates/jrsonnet-evaluator/src/stdlib/manifest.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/stdlib/manifest.rs
+++ b/crates/jrsonnet-evaluator/src/stdlib/manifest.rs
@@ -341,7 +341,7 @@
}
}
}
- Val::Func(_) => throw!(RuntimeError("tried to manifest function".into())),
+ Val::Func(_) => throw!("tried to manifest function"),
}
Ok(())
}
crates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/typed/conversions.rs
+++ b/crates/jrsonnet-evaluator/src/typed/conversions.rs
@@ -6,7 +6,7 @@
use jrsonnet_types::{ComplexValType, ValType};
use crate::{
- error::{Error::*, Result},
+ error::Result,
function::{FuncDesc, FuncVal},
throw,
typed::CheckType,
@@ -41,13 +41,10 @@
Val::Num(n) => {
#[allow(clippy::float_cmp)]
if n.trunc() != n {
- throw!(RuntimeError(
- format!(
- "cannot convert number with fractional part to {}",
- stringify!($ty)
- )
- .into()
- ))
+ throw!(
+ "cannot convert number with fractional part to {}",
+ stringify!($ty)
+ )
}
Ok(n as Self)
}
@@ -99,13 +96,10 @@
Val::Num(n) => {
#[allow(clippy::float_cmp)]
if n.trunc() != n {
- throw!(RuntimeError(
- format!(
- "cannot convert number with fractional part to {}",
- stringify!($ty)
- )
- .into()
- ))
+ throw!(
+ "cannot convert number with fractional part to {}",
+ stringify!($ty)
+ )
}
Ok(Self(n as $ty))
}
@@ -167,7 +161,7 @@
fn into_untyped(value: Self, _: State) -> Result<Val> {
if value > u32::MAX as Self {
- throw!(RuntimeError("number is too large".into()))
+ throw!("number is too large")
}
Ok(Val::Num(value as f64))
}
@@ -178,9 +172,7 @@
Val::Num(n) => {
#[allow(clippy::float_cmp)]
if n.trunc() != n {
- throw!(RuntimeError(
- "cannot convert number with fractional part to usize".into()
- ))
+ throw!("cannot convert number with fractional part to usize")
}
Ok(n as Self)
}
@@ -440,7 +432,7 @@
<Self as Typed>::TYPE.check(s, &value)?;
match value {
Val::Func(FuncVal::Normal(desc)) => Ok(desc),
- Val::Func(_) => throw!(RuntimeError("expected normal function, not builtin".into())),
+ Val::Func(_) => throw!("expected normal function, not builtin"),
_ => unreachable!(),
}
}
crates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/val.rs
+++ b/crates/jrsonnet-evaluator/src/val.rs
@@ -629,7 +629,7 @@
if num.is_finite() {
Ok(Self::Num(num))
} else {
- throw!(RuntimeError("overflow".into()))
+ throw!("overflow")
}
}
@@ -843,14 +843,14 @@
(Val::Null, Val::Null) => true,
(Val::Str(a), Val::Str(b)) => a == b,
(Val::Num(a), Val::Num(b)) => (a - b).abs() <= f64::EPSILON,
- (Val::Arr(_), Val::Arr(_)) => throw!(RuntimeError(
- "primitiveEquals operates on primitive types, got array".into(),
- )),
- (Val::Obj(_), Val::Obj(_)) => throw!(RuntimeError(
- "primitiveEquals operates on primitive types, got object".into(),
- )),
+ (Val::Arr(_), Val::Arr(_)) => {
+ throw!("primitiveEquals operates on primitive types, got array")
+ }
+ (Val::Obj(_), Val::Obj(_)) => {
+ throw!("primitiveEquals operates on primitive types, got object")
+ }
(a, b) if is_function_like(a) && is_function_like(b) => {
- throw!(RuntimeError("cannot test equality of functions".into()))
+ throw!("cannot test equality of functions")
}
(_, _) => false,
})
crates/jrsonnet-stdlib/src/arrays.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/arrays.rs
+++ b/crates/jrsonnet-stdlib/src/arrays.rs
@@ -1,7 +1,7 @@
use jrsonnet_evaluator::{
error::Result,
function::{builtin, FuncVal},
- throw_runtime,
+ throw,
typed::{Any, BoundedUsize, Typed, VecVal},
val::{equals, ArrValue, IndexableVal},
IStr, State, Val,
@@ -43,7 +43,7 @@
match func.evaluate_simple(s.clone(), &(c.to_string(),))? {
Val::Str(o) => out.push_str(&o),
Val::Null => continue,
- _ => throw_runtime!("in std.join all items should be strings"),
+ _ => throw!("in std.join all items should be strings"),
};
}
Ok(IndexableVal::Str(out.into()))
@@ -59,7 +59,7 @@
}
}
Val::Null => continue,
- _ => throw_runtime!("in std.join all items should be arrays"),
+ _ => throw!("in std.join all items should be arrays"),
};
}
Ok(IndexableVal::Arr(out.into()))
@@ -128,7 +128,7 @@
} else if matches!(item, Val::Null) {
continue;
} else {
- throw_runtime!("in std.join all items should be arrays");
+ throw!("in std.join all items should be arrays");
}
}
@@ -149,7 +149,7 @@
} else if matches!(item, Val::Null) {
continue;
} else {
- throw_runtime!("in std.join all items should be strings");
+ throw!("in std.join all items should be strings");
}
}
crates/jrsonnet-stdlib/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/lib.rs
+++ b/crates/jrsonnet-stdlib/src/lib.rs
@@ -8,7 +8,7 @@
error::{Error::*, Result},
function::{builtin::Builtin, ArgLike, CallLocation, FuncVal, TlaArg},
gc::{GcHashMap, TraceBox},
- tb, throw_runtime,
+ tb, throw,
trace::PathResolver,
typed::{Any, Either, Either2, Either4, VecVal, M1},
val::{equals, ArrValue},
@@ -500,7 +500,7 @@
true
}
}
- _ => throw_runtime!("both arguments should be of the same type"),
+ _ => throw!("both arguments should be of the same type"),
})
}
@@ -534,7 +534,7 @@
true
}
}
- _ => throw_runtime!("both arguments should be of the same type"),
+ _ => throw!("both arguments should be of the same type"),
})
}
crates/jrsonnet-stdlib/src/sort.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/sort.rs
+++ b/crates/jrsonnet-stdlib/src/sort.rs
@@ -1,7 +1,7 @@
use jrsonnet_evaluator::{
error::Result,
function::{builtin, FuncVal},
- throw_runtime,
+ throw,
typed::Any,
val::ArrValue,
State, Val,
@@ -41,9 +41,9 @@
(Val::Num(_), SortKeyType::Unknown) => sort_type = SortKeyType::Number,
(Val::Str(_), SortKeyType::String) | (Val::Num(_), SortKeyType::Number) => {}
(Val::Str(_) | Val::Num(_), _) => {
- throw_runtime!("sort elements should have the same types")
+ throw!("sort elements should have the same types")
}
- _ => throw_runtime!("sort key should either be a string or a number"),
+ _ => throw!("sort key should either be a string or a number"),
}
}
Ok(sort_type)
tests/tests/common.rsdiffbeforeafterboth--- a/tests/tests/common.rs
+++ b/tests/tests/common.rs
@@ -1,7 +1,7 @@
use jrsonnet_evaluator::{
error::Result,
function::{builtin, FuncVal},
- throw_runtime, ObjValueBuilder, State, Thunk, Val,
+ throw, ObjValueBuilder, State, Thunk, Val,
};
use jrsonnet_stdlib::StateExt;
@@ -11,7 +11,7 @@
let a = &$a;
let b = &$b;
if a != b {
- ::jrsonnet_evaluator::throw_runtime!("assertion failed: a != b\na={:#?}\nb={:#?}", a, b)
+ ::jrsonnet_evaluator::throw!("assertion failed: a != b\na={:#?}\nb={:#?}", a, b)
}
}};
}
@@ -20,7 +20,7 @@
macro_rules! ensure {
($v:expr $(,)?) => {
if !$v {
- ::jrsonnet_evaluator::throw_runtime!("assertion failed: {}", stringify!($v))
+ ::jrsonnet_evaluator::throw!("assertion failed: {}", stringify!($v))
}
};
}
@@ -29,7 +29,7 @@
macro_rules! ensure_val_eq {
($s:expr, $a:expr, $b:expr) => {{
if !::jrsonnet_evaluator::val::equals($s.clone(), &$a.clone(), &$b.clone())? {
- ::jrsonnet_evaluator::throw_runtime!(
+ ::jrsonnet_evaluator::throw!(
"assertion failed: a != b\na={:#?}\nb={:#?}",
$a.to_json(
$s.clone(),
@@ -52,7 +52,7 @@
fn assert_throw(s: State, lazy: Thunk<Val>, message: String) -> Result<bool> {
match lazy.evaluate(s) {
Ok(_) => {
- throw_runtime!("expected argument to throw on evaluation, but it returned instead")
+ throw!("expected argument to throw on evaluation, but it returned instead")
}
Err(e) => {
let error = format!("{}", e.error());
tests/tests/sanity.rsdiffbeforeafterboth--- a/tests/tests/sanity.rs
+++ b/tests/tests/sanity.rs
@@ -1,4 +1,4 @@
-use jrsonnet_evaluator::{error::Result, throw_runtime, State, Val};
+use jrsonnet_evaluator::{error::Result, throw, State, Val};
use jrsonnet_stdlib::StateExt;
mod common;
@@ -23,7 +23,7 @@
{
let e = match s.evaluate_snippet("snip".to_owned(), "assert 1 == 2: 'fail'; null") {
- Ok(_) => throw_runtime!("assertion should fail"),
+ Ok(_) => throw!("assertion should fail"),
Err(e) => e,
};
let e = s.stringify_err(&e);
@@ -31,7 +31,7 @@
}
{
let e = match s.evaluate_snippet("snip".to_owned(), "std.assertEqual(1, 2)") {
- Ok(_) => throw_runtime!("assertion should fail"),
+ Ok(_) => throw!("assertion should fail"),
Err(e) => e,
};
let e = s.stringify_err(&e);