pub unsafe fn define<T: AsRef<str>>(
        name: T,
        key_ty: LLVMTypeRef,
        key_comparator: LLVMValueRef,
        val_ty: LLVMTypeRef,
        context: LLVMContextRef,
        module: LLVMModuleRef,
    ) -> Dict {
        let c_name = CString::new(name.as_ref()).unwrap();
        let slot_ty = SlotType::new(
            format!("{}.slot", name.as_ref()),
            key_ty,
            val_ty,
            context,
            module,
        );

        // A dictionary holds an array of slots along with a capacity and size.
        let mut layout = [
            LLVMPointerType(slot_ty.slot_ty, 0),
            LLVMInt64TypeInContext(context),
            LLVMInt64TypeInContext(context),
        ];

        debug_assert!(
            LLVMGetTypeKind(layout[SLOT_ARR_INDEX as usize]) == LLVMTypeKind::LLVMPointerTypeKind
        );
        debug_assert!(
            LLVMGetTypeKind(layout[CAP_INDEX as usize]) == LLVMTypeKind::LLVMIntegerTypeKind
        );
        debug_assert!(
            LLVMGetTypeKind(layout[SIZE_INDEX as usize]) == LLVMTypeKind::LLVMIntegerTypeKind
        );

        let dict_inner_ty = LLVMStructCreateNamed(context, c_name.as_ptr());
        LLVMStructSetBody(dict_inner_ty, layout.as_mut_ptr(), layout.len() as u32, 0);

        let name = c_name.into_string().unwrap();

        Dict {
            name,
            dict_ty: LLVMPointerType(dict_inner_ty, 0),
            dict_inner_ty,
            key_comparator,
            slot_ty,
            context,
            module,
            slot_for_key: None,
            new: None,
            lookup: None,
            opt_lookup: None,
            upsert: None,
            resize: None,
            key_exists: None,
            to_vec: None,
            merge_grouped: None,
        }
    }
Define a new dictionary type.

The definition requires a key and a value type.
weld/src/codegen/llvm2/dict.rs