[core] codegen: Refactor TypedArrayLikeAdapter to use fn

Allows for greater flexibility when TypedArrayLikeAdapter is used with
custom value types.
This commit is contained in:
David Mak 2024-12-17 18:03:03 +08:00
parent 35b49dc279
commit a2efccee1c
6 changed files with 117 additions and 108 deletions

View File

@ -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(),
)
}

View File

@ -356,7 +356,7 @@ where
ValueFn: Fn(
&mut G,
&mut CodeGenContext<'ctx, 'a>,
&TypedArrayLikeAdapter<'ctx, IntValue<'ctx>>,
&TypedArrayLikeAdapter<'ctx, G, IntValue<'ctx>>,
) -> Result<BasicValueEnum<'ctx>, String>,
{
ndarray_fill_flattened(generator, ctx, ndarray, |generator, ctx, idx| {

View File

@ -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<G: CodeGenerator + ?Sized>(
&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<G: CodeGenerator + ?Sized>(
&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<G: CodeGenerator + ?Sized>(
&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<G: CodeGenerator + ?Sized>(
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<G: CodeGenerator + ?Sized>(
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<G: CodeGenerator + ?Sized>(
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<G: CodeGenerator + ?Sized>(
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<dyn Fn(&mut CodeGenContext<'ctx, '_>, BasicValueEnum<'ctx>) -> T + 'ctx>;
/// Type alias for a function that casts a `T` into a [`BasicValueEnum`].
type ValueUpcastFn<'ctx, T> = Box<dyn Fn(&mut CodeGenContext<'ctx, '_>, 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<G: CodeGenerator + ?Sized>(
fn element_type<CG: CodeGenerator + ?Sized>(
&self,
ctx: &CodeGenContext<'ctx, '_>,
generator: &G,
generator: &CG,
) -> AnyTypeEnum<'ctx> {
self.adapted.element_type(ctx, generator)
}
fn base_ptr<G: CodeGenerator + ?Sized>(
fn base_ptr<CG: CodeGenerator + ?Sized>(
&self,
ctx: &CodeGenContext<'ctx, '_>,
generator: &G,
generator: &CG,
) -> PointerValue<'ctx> {
self.adapted.base_ptr(ctx, generator)
}
fn size<G: CodeGenerator + ?Sized>(
fn size<CG: CodeGenerator + ?Sized>(
&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<G: CodeGenerator + ?Sized>(
unsafe fn ptr_offset_unchecked<CG: CodeGenerator + ?Sized>(
&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<G: CodeGenerator + ?Sized>(
fn ptr_offset<CG: CodeGenerator + ?Sized>(
&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<G: CodeGenerator + ?Sized>(
&self,
ctx: &mut CodeGenContext<'ctx, '_>,
generator: &mut G,
ctx: &CodeGenContext<'ctx, '_>,
generator: &G,
idx: &IntValue<'ctx>,
name: Option<&str>,
) -> PointerValue<'ctx> {

View File

@ -199,8 +199,8 @@ impl<'ctx> ArrayLikeValue<'ctx> for ListDataProxy<'ctx, '_> {
impl<'ctx> ArrayLikeIndexer<'ctx> for ListDataProxy<'ctx, '_> {
unsafe fn ptr_offset_unchecked<G: CodeGenerator + ?Sized>(
&self,
ctx: &mut CodeGenContext<'ctx, '_>,
generator: &mut G,
ctx: &CodeGenContext<'ctx, '_>,
generator: &G,
idx: &IntValue<'ctx>,
name: Option<&str>,
) -> PointerValue<'ctx> {

View File

@ -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<G: CodeGenerator + ?Sized>(
&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<G: CodeGenerator + ?Sized>(
&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<G: CodeGenerator + ?Sized>(
&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<G: CodeGenerator + ?Sized>(
&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)
let indices_elem_ty = unsafe {
indices
.ptr_offset_unchecked(ctx, generator, &llvm_usize.const_zero(), None)
.get_type()
.get_element_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}")
};

View File

@ -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<G: CodeGenerator + ?Sized>(
&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(),
)
}
}