difftreelog
feat thunk conversion avoiding lazy
in: master
1 file changed
crates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth1use std::{collections::BTreeMap, marker::PhantomData, ops::Deref};1use std::{any::TypeId, collections::BTreeMap, marker::PhantomData, mem::transmute, ops::Deref};223use jrsonnet_gcmodule::Trace;3use jrsonnet_gcmodule::Trace;4use jrsonnet_interner::{IBytes, IStr};4use jrsonnet_interner::{IBytes, IStr};5use jrsonnet_types::{ComplexValType, ValType};5use jrsonnet_types::{ComplexValType, ValType};667use crate::{7use crate::{8 ObjValue, ObjValueBuilder, Result, ResultExt, Thunk, Val,9 arr::{ArrValue, BytesArray},8 arr::{ArrValue, BytesArray},10 bail,9 bail,11 function::FuncVal,10 function::FuncVal,12 typed::CheckType,11 typed::CheckType,13 val::{IndexableVal, NumValue, StrValue, ThunkMapper},12 val::{IndexableVal, NumValue, StrValue, ThunkMapper},13 ObjValue, ObjValueBuilder, Result, ResultExt, Thunk, Val,14};14};151516#[doc(hidden)]16#[doc(hidden)]17pub mod __typed_macro_prelude {17pub mod __typed_macro_prelude {18 pub use ::jrsonnet_evaluator::{18 pub use ::jrsonnet_evaluator::{19 IStr, ObjValue, ObjValueBuilder, State, Val,20 error::{ErrorKind, Result as JrResult},19 error::{ErrorKind, Result as JrResult},21 typed::{20 typed::{22 CheckType, ComplexValType, FromUntyped, IntoUntyped, ParseTypedObj, SerializeTypedObj,21 CheckType, ComplexValType, FromUntyped, IntoUntyped, ParseTypedObj, SerializeTypedObj,23 Typed,22 Typed,24 },23 },24 IStr, ObjValue, ObjValueBuilder, State, Val,25 };25 };26}26}27pub use jrsonnet_macros::{FromUntyped, IntoUntyped, Typed};27pub use jrsonnet_macros::{FromUntyped, IntoUntyped, Typed};127 const TYPE: &'static ComplexValType = &ComplexValType::Lazy(T::TYPE);127 const TYPE: &'static ComplexValType = &ComplexValType::Lazy(T::TYPE);128}128}129129130fn try_cast_thunk_val<T: 'static>(typed: Thunk<T>) -> Result<Thunk<Val>, Thunk<T>> {131 if TypeId::of::<T>() == TypeId::of::<Val>() {132 // SAFETY: We know that it is exactly the same type, and we discard the original after that133 // to avoid double-free.134 let transmuted = unsafe { transmute::<Thunk<T>, Thunk<Val>>(typed) };135 Ok(transmuted)136 } else {137 Err(typed)138 }139}130impl IntoUntyped for Thunk<Val> {140impl<T> IntoUntyped for Thunk<T>141where142 T: IntoUntyped + Trace + Clone,143{131 fn into_untyped(typed: Self) -> Result<Val> {144 fn into_untyped(typed: Self) -> Result<Val> {132 typed.evaluate()145 T::into_untyped(typed.evaluate()?)133 }146 }134 fn provides_lazy() -> bool {147 fn provides_lazy() -> bool {135 true148 true136 }149 }137150138 fn into_lazy_untyped(inner: Self) -> Thunk<Val> {151 fn into_lazy_untyped(inner: Self) -> Thunk<Val> {152 // Avoid lazy mapping139 inner153 let inner = match try_cast_thunk_val(inner) {154 Ok(v) => return v,155 Err(e) => e,156 };157 inner.map(<ThunkIntoUntyped<T>>::default())140 }158 }141}159}142160161fn try_cast_thunk_t<T: 'static>(typed: Thunk<Val>) -> Result<Thunk<T>, Thunk<Val>> {162 if TypeId::of::<T>() == TypeId::of::<Val>() {163 // SAFETY: We know that it is exactly the same type, and we discard the original after that164 // to avoid double-free.165 let transmuted = unsafe { transmute::<Thunk<Val>, Thunk<T>>(typed) };166 Ok(transmuted)167 } else {168 Err(typed)169 }170}143impl<T> FromUntyped for Thunk<T>171impl<T> FromUntyped for Thunk<T>144where172where145 T: Typed + FromUntyped + Trace + Clone,173 T: Typed + FromUntyped + Trace + Clone,153 }181 }154182155 fn from_lazy_untyped(inner: Thunk<Val>) -> Result<Self> {183 fn from_lazy_untyped(inner: Thunk<Val>) -> Result<Self> {184 // Avoid lazy mapping185 let inner = match try_cast_thunk_t(inner) {186 Ok(v) => return Ok(v),187 Err(e) => e,188 };156 Ok(inner.map(<ThunkFromUntyped<T>>::default()))189 Ok(inner.map(<ThunkFromUntyped<T>>::default()))157 }190 }158}191}