diff --git a/nac3core/src/codegen/irrt/ndarray/mod.rs b/nac3core/src/codegen/irrt/ndarray/mod.rs index a05e0ce3..56d9094d 100644 --- a/nac3core/src/codegen/irrt/ndarray/mod.rs +++ b/nac3core/src/codegen/irrt/ndarray/mod.rs @@ -87,7 +87,7 @@ pub fn call_ndarray_calc_nd_indices<'ctx, G: CodeGenerator + ?Sized>( ctx: &CodeGenContext<'ctx, '_>, index: IntValue<'ctx>, ndarray: NDArrayValue<'ctx>, -) -> TypedArrayLikeAdapter<'ctx, IntValue<'ctx>> { +) -> TypedArrayLikeAdapter<'ctx, G, IntValue<'ctx>> { let llvm_void = ctx.ctx.void_type(); let llvm_i32 = ctx.ctx.i32_type(); let llvm_usize = generator.get_size_type(ctx.ctx); @@ -129,8 +129,8 @@ pub fn call_ndarray_calc_nd_indices<'ctx, G: CodeGenerator + ?Sized>( TypedArrayLikeAdapter::from( ArraySliceValue::from_ptr_val(indices, ndarray_num_dims, None), - Box::new(|_, v| v.into_int_value()), - Box::new(|_, v| v.into()), + |_, _, v| v.into_int_value(), + |_, _, v| v.into(), ) } @@ -227,7 +227,7 @@ pub fn call_ndarray_calc_broadcast<'ctx, G: CodeGenerator + ?Sized>( ctx: &mut CodeGenContext<'ctx, '_>, lhs: NDArrayValue<'ctx>, rhs: NDArrayValue<'ctx>, -) -> TypedArrayLikeAdapter<'ctx, IntValue<'ctx>> { +) -> TypedArrayLikeAdapter<'ctx, G, IntValue<'ctx>> { let llvm_usize = generator.get_size_type(ctx.ctx); let llvm_pusize = llvm_usize.ptr_type(AddressSpace::default()); @@ -326,11 +326,7 @@ pub fn call_ndarray_calc_broadcast<'ctx, G: CodeGenerator + ?Sized>( ) .unwrap(); - TypedArrayLikeAdapter::from( - out_dims, - Box::new(|_, v| v.into_int_value()), - Box::new(|_, v| v.into()), - ) + TypedArrayLikeAdapter::from(out_dims, |_, _, v| v.into_int_value(), |_, _, v| v.into()) } /// Generates a call to `__nac3_ndarray_calc_broadcast_idx`. Returns an [`ArrayAllocaValue`] @@ -345,7 +341,7 @@ pub fn call_ndarray_calc_broadcast_index< ctx: &mut CodeGenContext<'ctx, '_>, array: NDArrayValue<'ctx>, broadcast_idx: &BroadcastIdx, -) -> TypedArrayLikeAdapter<'ctx, IntValue<'ctx>> { +) -> TypedArrayLikeAdapter<'ctx, G, IntValue<'ctx>> { let llvm_i32 = ctx.ctx.i32_type(); let llvm_usize = generator.get_size_type(ctx.ctx); let llvm_pi32 = llvm_i32.ptr_type(AddressSpace::default()); @@ -385,7 +381,7 @@ pub fn call_ndarray_calc_broadcast_index< TypedArrayLikeAdapter::from( ArraySliceValue::from_ptr_val(out_idx, broadcast_size, None), - Box::new(|_, v| v.into_int_value()), - Box::new(|_, v| v.into()), + |_, _, v| v.into_int_value(), + |_, _, v| v.into(), ) } diff --git a/nac3core/src/codegen/numpy.rs b/nac3core/src/codegen/numpy.rs index 513f8f51..30a33f08 100644 --- a/nac3core/src/codegen/numpy.rs +++ b/nac3core/src/codegen/numpy.rs @@ -356,7 +356,7 @@ where ValueFn: Fn( &mut G, &mut CodeGenContext<'ctx, 'a>, - &TypedArrayLikeAdapter<'ctx, IntValue<'ctx>>, + &TypedArrayLikeAdapter<'ctx, G, IntValue<'ctx>>, ) -> Result, String>, { ndarray_fill_flattened(generator, ctx, ndarray, |generator, ctx, idx| { diff --git a/nac3core/src/codegen/values/array.rs b/nac3core/src/codegen/values/array.rs index e6ebb258..9f3ec0e4 100644 --- a/nac3core/src/codegen/values/array.rs +++ b/nac3core/src/codegen/values/array.rs @@ -51,8 +51,8 @@ pub trait ArrayLikeIndexer<'ctx, Index = IntValue<'ctx>>: ArrayLikeValue<'ctx> { /// This function should be called with a valid index. unsafe fn ptr_offset_unchecked( &self, - ctx: &mut CodeGenContext<'ctx, '_>, - generator: &mut G, + ctx: &CodeGenContext<'ctx, '_>, + generator: &G, idx: &Index, name: Option<&str>, ) -> PointerValue<'ctx>; @@ -76,8 +76,8 @@ pub trait UntypedArrayLikeAccessor<'ctx, Index = IntValue<'ctx>>: /// This function should be called with a valid index. unsafe fn get_unchecked( &self, - ctx: &mut CodeGenContext<'ctx, '_>, - generator: &mut G, + ctx: &CodeGenContext<'ctx, '_>, + generator: &G, idx: &Index, name: Option<&str>, ) -> BasicValueEnum<'ctx> { @@ -107,8 +107,8 @@ pub trait UntypedArrayLikeMutator<'ctx, Index = IntValue<'ctx>>: /// This function should be called with a valid index. unsafe fn set_unchecked( &self, - ctx: &mut CodeGenContext<'ctx, '_>, - generator: &mut G, + ctx: &CodeGenContext<'ctx, '_>, + generator: &G, idx: &Index, value: BasicValueEnum<'ctx>, ) { @@ -130,32 +130,33 @@ pub trait UntypedArrayLikeMutator<'ctx, Index = IntValue<'ctx>>: } /// An array-like value that can have its array elements accessed as an arbitrary type `T`. -pub trait TypedArrayLikeAccessor<'ctx, T, Index = IntValue<'ctx>>: +pub trait TypedArrayLikeAccessor<'ctx, G: CodeGenerator + ?Sized, T, Index = IntValue<'ctx>>: UntypedArrayLikeAccessor<'ctx, Index> { /// Casts an element from [`BasicValueEnum`] into `T`. fn downcast_to_type( &self, - ctx: &mut CodeGenContext<'ctx, '_>, + ctx: &CodeGenContext<'ctx, '_>, + generator: &G, value: BasicValueEnum<'ctx>, ) -> T; /// # Safety /// /// This function should be called with a valid index. - unsafe fn get_typed_unchecked( + unsafe fn get_typed_unchecked( &self, - ctx: &mut CodeGenContext<'ctx, '_>, - generator: &mut G, + ctx: &CodeGenContext<'ctx, '_>, + generator: &G, idx: &Index, name: Option<&str>, ) -> T { let value = unsafe { self.get_unchecked(ctx, generator, idx, name) }; - self.downcast_to_type(ctx, value) + self.downcast_to_type(ctx, generator, value) } /// Returns the data at the `idx`-th index. - fn get_typed( + fn get_typed( &self, ctx: &mut CodeGenContext<'ctx, '_>, generator: &mut G, @@ -163,62 +164,62 @@ pub trait TypedArrayLikeAccessor<'ctx, T, Index = IntValue<'ctx>>: name: Option<&str>, ) -> T { let value = self.get(ctx, generator, idx, name); - self.downcast_to_type(ctx, value) + self.downcast_to_type(ctx, generator, value) } } /// An array-like value that can have its array elements mutated as an arbitrary type `T`. -pub trait TypedArrayLikeMutator<'ctx, T, Index = IntValue<'ctx>>: +pub trait TypedArrayLikeMutator<'ctx, G: CodeGenerator + ?Sized, T, Index = IntValue<'ctx>>: UntypedArrayLikeMutator<'ctx, Index> { /// Casts an element from T into [`BasicValueEnum`]. fn upcast_from_type( &self, - ctx: &mut CodeGenContext<'ctx, '_>, + ctx: &CodeGenContext<'ctx, '_>, + generator: &G, value: T, ) -> BasicValueEnum<'ctx>; /// # Safety /// /// This function should be called with a valid index. - unsafe fn set_typed_unchecked( + unsafe fn set_typed_unchecked( &self, - ctx: &mut CodeGenContext<'ctx, '_>, - generator: &mut G, + ctx: &CodeGenContext<'ctx, '_>, + generator: &G, idx: &Index, value: T, ) { - let value = self.upcast_from_type(ctx, value); + let value = self.upcast_from_type(ctx, generator, value); unsafe { self.set_unchecked(ctx, generator, idx, value) } } /// Sets the data at the `idx`-th index. - fn set_typed( + fn set_typed( &self, ctx: &mut CodeGenContext<'ctx, '_>, generator: &mut G, idx: &Index, value: T, ) { - let value = self.upcast_from_type(ctx, value); + let value = self.upcast_from_type(ctx, generator, value); self.set(ctx, generator, idx, value); } } -/// Type alias for a function that casts a [`BasicValueEnum`] into a `T`. -type ValueDowncastFn<'ctx, T> = - Box, BasicValueEnum<'ctx>) -> T + 'ctx>; -/// Type alias for a function that casts a `T` into a [`BasicValueEnum`]. -type ValueUpcastFn<'ctx, T> = Box, T) -> BasicValueEnum<'ctx>>; - /// An adapter for constraining untyped array values as typed values. -pub struct TypedArrayLikeAdapter<'ctx, T, Adapted: ArrayLikeValue<'ctx> = ArraySliceValue<'ctx>> { +pub struct TypedArrayLikeAdapter< + 'ctx, + G: CodeGenerator + ?Sized, + T, + Adapted: ArrayLikeValue<'ctx> = ArraySliceValue<'ctx>, +> { adapted: Adapted, - downcast_fn: ValueDowncastFn<'ctx, T>, - upcast_fn: ValueUpcastFn<'ctx, T>, + downcast_fn: fn(&CodeGenContext<'ctx, '_>, &G, BasicValueEnum<'ctx>) -> T, + upcast_fn: fn(&CodeGenContext<'ctx, '_>, &G, T) -> BasicValueEnum<'ctx>, } -impl<'ctx, T, Adapted> TypedArrayLikeAdapter<'ctx, T, Adapted> +impl<'ctx, G: CodeGenerator + ?Sized, T, Adapted> TypedArrayLikeAdapter<'ctx, G, T, Adapted> where Adapted: ArrayLikeValue<'ctx>, { @@ -229,61 +230,62 @@ where /// * `upcast_fn` - The function converting a T into a [`BasicValueEnum`]. pub fn from( adapted: Adapted, - downcast_fn: ValueDowncastFn<'ctx, T>, - upcast_fn: ValueUpcastFn<'ctx, T>, + downcast_fn: fn(&CodeGenContext<'ctx, '_>, &G, BasicValueEnum<'ctx>) -> T, + upcast_fn: fn(&CodeGenContext<'ctx, '_>, &G, T) -> BasicValueEnum<'ctx>, ) -> Self { TypedArrayLikeAdapter { adapted, downcast_fn, upcast_fn } } } -impl<'ctx, T, Adapted> ArrayLikeValue<'ctx> for TypedArrayLikeAdapter<'ctx, T, Adapted> +impl<'ctx, G: CodeGenerator + ?Sized, T, Adapted> ArrayLikeValue<'ctx> + for TypedArrayLikeAdapter<'ctx, G, T, Adapted> where Adapted: ArrayLikeValue<'ctx>, { - fn element_type( + fn element_type( &self, ctx: &CodeGenContext<'ctx, '_>, - generator: &G, + generator: &CG, ) -> AnyTypeEnum<'ctx> { self.adapted.element_type(ctx, generator) } - fn base_ptr( + fn base_ptr( &self, ctx: &CodeGenContext<'ctx, '_>, - generator: &G, + generator: &CG, ) -> PointerValue<'ctx> { self.adapted.base_ptr(ctx, generator) } - fn size( + fn size( &self, ctx: &CodeGenContext<'ctx, '_>, - generator: &G, + generator: &CG, ) -> IntValue<'ctx> { self.adapted.size(ctx, generator) } } -impl<'ctx, T, Index, Adapted> ArrayLikeIndexer<'ctx, Index> - for TypedArrayLikeAdapter<'ctx, T, Adapted> +impl<'ctx, G: CodeGenerator + ?Sized, T, Index, Adapted> ArrayLikeIndexer<'ctx, Index> + for TypedArrayLikeAdapter<'ctx, G, T, Adapted> where Adapted: ArrayLikeIndexer<'ctx, Index>, { - unsafe fn ptr_offset_unchecked( + unsafe fn ptr_offset_unchecked( &self, - ctx: &mut CodeGenContext<'ctx, '_>, - generator: &mut G, + ctx: &CodeGenContext<'ctx, '_>, + generator: &CG, idx: &Index, name: Option<&str>, ) -> PointerValue<'ctx> { unsafe { self.adapted.ptr_offset_unchecked(ctx, generator, idx, name) } } - fn ptr_offset( + fn ptr_offset( &self, ctx: &mut CodeGenContext<'ctx, '_>, - generator: &mut G, + generator: &mut CG, idx: &Index, name: Option<&str>, ) -> PointerValue<'ctx> { @@ -291,44 +293,46 @@ where } } -impl<'ctx, T, Index, Adapted> UntypedArrayLikeAccessor<'ctx, Index> - for TypedArrayLikeAdapter<'ctx, T, Adapted> +impl<'ctx, G: CodeGenerator + ?Sized, T, Index, Adapted> UntypedArrayLikeAccessor<'ctx, Index> + for TypedArrayLikeAdapter<'ctx, G, T, Adapted> where Adapted: UntypedArrayLikeAccessor<'ctx, Index>, { } -impl<'ctx, T, Index, Adapted> UntypedArrayLikeMutator<'ctx, Index> - for TypedArrayLikeAdapter<'ctx, T, Adapted> +impl<'ctx, G: CodeGenerator + ?Sized, T, Index, Adapted> UntypedArrayLikeMutator<'ctx, Index> + for TypedArrayLikeAdapter<'ctx, G, T, Adapted> where Adapted: UntypedArrayLikeMutator<'ctx, Index>, { } -impl<'ctx, T, Index, Adapted> TypedArrayLikeAccessor<'ctx, T, Index> - for TypedArrayLikeAdapter<'ctx, T, Adapted> +impl<'ctx, G: CodeGenerator + ?Sized, T, Index, Adapted> TypedArrayLikeAccessor<'ctx, G, T, Index> + for TypedArrayLikeAdapter<'ctx, G, T, Adapted> where Adapted: UntypedArrayLikeAccessor<'ctx, Index>, { fn downcast_to_type( &self, - ctx: &mut CodeGenContext<'ctx, '_>, + ctx: &CodeGenContext<'ctx, '_>, + generator: &G, value: BasicValueEnum<'ctx>, ) -> T { - (self.downcast_fn)(ctx, value) + (self.downcast_fn)(ctx, generator, value) } } -impl<'ctx, T, Index, Adapted> TypedArrayLikeMutator<'ctx, T, Index> - for TypedArrayLikeAdapter<'ctx, T, Adapted> +impl<'ctx, G: CodeGenerator + ?Sized, T, Index, Adapted> TypedArrayLikeMutator<'ctx, G, T, Index> + for TypedArrayLikeAdapter<'ctx, G, T, Adapted> where Adapted: UntypedArrayLikeMutator<'ctx, Index>, { fn upcast_from_type( &self, - ctx: &mut CodeGenContext<'ctx, '_>, + ctx: &CodeGenContext<'ctx, '_>, + generator: &G, value: T, ) -> BasicValueEnum<'ctx> { - (self.upcast_fn)(ctx, value) + (self.upcast_fn)(ctx, generator, value) } } @@ -384,8 +388,8 @@ impl<'ctx> ArrayLikeValue<'ctx> for ArraySliceValue<'ctx> { impl<'ctx> ArrayLikeIndexer<'ctx> for ArraySliceValue<'ctx> { unsafe fn ptr_offset_unchecked( &self, - ctx: &mut CodeGenContext<'ctx, '_>, - generator: &mut G, + ctx: &CodeGenContext<'ctx, '_>, + generator: &G, idx: &IntValue<'ctx>, name: Option<&str>, ) -> PointerValue<'ctx> { diff --git a/nac3core/src/codegen/values/list.rs b/nac3core/src/codegen/values/list.rs index 7b1975f0..549bfe3f 100644 --- a/nac3core/src/codegen/values/list.rs +++ b/nac3core/src/codegen/values/list.rs @@ -199,8 +199,8 @@ impl<'ctx> ArrayLikeValue<'ctx> for ListDataProxy<'ctx, '_> { impl<'ctx> ArrayLikeIndexer<'ctx> for ListDataProxy<'ctx, '_> { unsafe fn ptr_offset_unchecked( &self, - ctx: &mut CodeGenContext<'ctx, '_>, - generator: &mut G, + ctx: &CodeGenContext<'ctx, '_>, + generator: &G, idx: &IntValue<'ctx>, name: Option<&str>, ) -> PointerValue<'ctx> { diff --git a/nac3core/src/codegen/values/ndarray/mod.rs b/nac3core/src/codegen/values/ndarray/mod.rs index eef74407..0da3a2ee 100644 --- a/nac3core/src/codegen/values/ndarray/mod.rs +++ b/nac3core/src/codegen/values/ndarray/mod.rs @@ -478,8 +478,8 @@ impl<'ctx> ArrayLikeValue<'ctx> for NDArrayShapeProxy<'ctx, '_> { impl<'ctx> ArrayLikeIndexer<'ctx, IntValue<'ctx>> for NDArrayShapeProxy<'ctx, '_> { unsafe fn ptr_offset_unchecked( &self, - ctx: &mut CodeGenContext<'ctx, '_>, - generator: &mut G, + ctx: &CodeGenContext<'ctx, '_>, + generator: &G, idx: &IntValue<'ctx>, name: Option<&str>, ) -> PointerValue<'ctx> { @@ -517,20 +517,26 @@ impl<'ctx> ArrayLikeIndexer<'ctx, IntValue<'ctx>> for NDArrayShapeProxy<'ctx, '_ impl<'ctx> UntypedArrayLikeAccessor<'ctx, IntValue<'ctx>> for NDArrayShapeProxy<'ctx, '_> {} impl<'ctx> UntypedArrayLikeMutator<'ctx, IntValue<'ctx>> for NDArrayShapeProxy<'ctx, '_> {} -impl<'ctx> TypedArrayLikeAccessor<'ctx, IntValue<'ctx>> for NDArrayShapeProxy<'ctx, '_> { +impl<'ctx, G: CodeGenerator + ?Sized> TypedArrayLikeAccessor<'ctx, G, IntValue<'ctx>> + for NDArrayShapeProxy<'ctx, '_> +{ fn downcast_to_type( &self, - _: &mut CodeGenContext<'ctx, '_>, + _: &CodeGenContext<'ctx, '_>, + _: &G, value: BasicValueEnum<'ctx>, ) -> IntValue<'ctx> { value.into_int_value() } } -impl<'ctx> TypedArrayLikeMutator<'ctx, IntValue<'ctx>> for NDArrayShapeProxy<'ctx, '_> { +impl<'ctx, G: CodeGenerator + ?Sized> TypedArrayLikeMutator<'ctx, G, IntValue<'ctx>> + for NDArrayShapeProxy<'ctx, '_> +{ fn upcast_from_type( &self, - _: &mut CodeGenContext<'ctx, '_>, + _: &CodeGenContext<'ctx, '_>, + _: &G, value: IntValue<'ctx>, ) -> BasicValueEnum<'ctx> { value.into() @@ -570,8 +576,8 @@ impl<'ctx> ArrayLikeValue<'ctx> for NDArrayStridesProxy<'ctx, '_> { impl<'ctx> ArrayLikeIndexer<'ctx, IntValue<'ctx>> for NDArrayStridesProxy<'ctx, '_> { unsafe fn ptr_offset_unchecked( &self, - ctx: &mut CodeGenContext<'ctx, '_>, - generator: &mut G, + ctx: &CodeGenContext<'ctx, '_>, + generator: &G, idx: &IntValue<'ctx>, name: Option<&str>, ) -> PointerValue<'ctx> { @@ -609,20 +615,26 @@ impl<'ctx> ArrayLikeIndexer<'ctx, IntValue<'ctx>> for NDArrayStridesProxy<'ctx, impl<'ctx> UntypedArrayLikeAccessor<'ctx, IntValue<'ctx>> for NDArrayStridesProxy<'ctx, '_> {} impl<'ctx> UntypedArrayLikeMutator<'ctx, IntValue<'ctx>> for NDArrayStridesProxy<'ctx, '_> {} -impl<'ctx> TypedArrayLikeAccessor<'ctx, IntValue<'ctx>> for NDArrayStridesProxy<'ctx, '_> { +impl<'ctx, G: CodeGenerator + ?Sized> TypedArrayLikeAccessor<'ctx, G, IntValue<'ctx>> + for NDArrayStridesProxy<'ctx, '_> +{ fn downcast_to_type( &self, - _: &mut CodeGenContext<'ctx, '_>, + _: &CodeGenContext<'ctx, '_>, + _: &G, value: BasicValueEnum<'ctx>, ) -> IntValue<'ctx> { value.into_int_value() } } -impl<'ctx> TypedArrayLikeMutator<'ctx, IntValue<'ctx>> for NDArrayStridesProxy<'ctx, '_> { +impl<'ctx, G: CodeGenerator + ?Sized> TypedArrayLikeMutator<'ctx, G, IntValue<'ctx>> + for NDArrayStridesProxy<'ctx, '_> +{ fn upcast_from_type( &self, - _: &mut CodeGenContext<'ctx, '_>, + _: &CodeGenContext<'ctx, '_>, + _: &G, value: IntValue<'ctx>, ) -> BasicValueEnum<'ctx> { value.into() @@ -667,8 +679,8 @@ impl<'ctx> ArrayLikeValue<'ctx> for NDArrayDataProxy<'ctx, '_> { impl<'ctx> ArrayLikeIndexer<'ctx> for NDArrayDataProxy<'ctx, '_> { unsafe fn ptr_offset_unchecked( &self, - ctx: &mut CodeGenContext<'ctx, '_>, - generator: &mut G, + ctx: &CodeGenContext<'ctx, '_>, + generator: &G, idx: &IntValue<'ctx>, name: Option<&str>, ) -> PointerValue<'ctx> { @@ -748,17 +760,19 @@ impl<'ctx, Index: UntypedArrayLikeAccessor<'ctx>> ArrayLikeIndexer<'ctx, Index> { unsafe fn ptr_offset_unchecked( &self, - ctx: &mut CodeGenContext<'ctx, '_>, - generator: &mut G, + ctx: &CodeGenContext<'ctx, '_>, + generator: &G, indices: &Index, name: Option<&str>, ) -> PointerValue<'ctx> { let llvm_usize = generator.get_size_type(ctx.ctx); - let indices_elem_ty = indices - .ptr_offset(ctx, generator, &llvm_usize.const_zero(), None) - .get_type() - .get_element_type(); + let indices_elem_ty = unsafe { + indices + .ptr_offset_unchecked(ctx, generator, &llvm_usize.const_zero(), None) + .get_type() + .get_element_type() + }; let Ok(indices_elem_ty) = IntType::try_from(indices_elem_ty) else { panic!("Expected list[int32] but got {indices_elem_ty}") }; diff --git a/nac3core/src/codegen/values/ndarray/nditer.rs b/nac3core/src/codegen/values/ndarray/nditer.rs index c50a3878..22f1bcad 100644 --- a/nac3core/src/codegen/values/ndarray/nditer.rs +++ b/nac3core/src/codegen/values/ndarray/nditer.rs @@ -4,7 +4,7 @@ use inkwell::{ AddressSpace, }; -use super::{NDArrayValue, ProxyValue, TypedArrayLikeAccessor, TypedArrayLikeMutator}; +use super::{NDArrayValue, ProxyValue}; use crate::codegen::{ irrt, stmt::{gen_for_callback, BreakContinueHooks}, @@ -103,18 +103,13 @@ impl<'ctx> NDIterValue<'ctx> { /// Get the indices of the current element. #[must_use] - pub fn get_indices( - &'ctx self, - ) -> impl TypedArrayLikeAccessor<'ctx, IntValue<'ctx>> + TypedArrayLikeMutator<'ctx, IntValue<'ctx>> - { + pub fn get_indices( + &self, + ) -> TypedArrayLikeAdapter<'ctx, G, IntValue<'ctx>> { TypedArrayLikeAdapter::from( self.indices, - Box::new(|ctx, val| { - ctx.builder - .build_int_z_extend_or_bit_cast(val.into_int_value(), self.llvm_usize, "") - .unwrap() - }), - Box::new(|_, val| val.into()), + |_, _, val| val.into_int_value(), + |_, _, val| val.into(), ) } }