add implicit casts from *[N]T

* to `[]T`
 * to `[*]T`

See #770
This commit is contained in:
Andrew Kelley
2018-06-07 22:19:00 -04:00
parent b65203f573
commit f0b6dac1f2
4 changed files with 163 additions and 2 deletions

View File

@@ -2530,7 +2530,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
assert(wanted_type->data.structure.is_slice);
assert(actual_type->id == TypeTableEntryIdArray);
TypeTableEntry *wanted_pointer_type = wanted_type->data.structure.fields[0].type_entry;
TypeTableEntry *wanted_pointer_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
TypeTableEntry *wanted_child_type = wanted_pointer_type->data.pointer.child_type;
@@ -2576,6 +2576,29 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
return expr_val;
case CastOpBitCast:
return LLVMBuildBitCast(g->builder, expr_val, wanted_type->type_ref, "");
case CastOpPtrOfArrayToSlice: {
assert(cast_instruction->tmp_ptr);
assert(actual_type->id == TypeTableEntryIdPointer);
TypeTableEntry *array_type = actual_type->data.pointer.child_type;
assert(array_type->id == TypeTableEntryIdArray);
LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr,
slice_ptr_index, "");
LLVMValueRef indices[] = {
LLVMConstNull(g->builtin_types.entry_usize->type_ref),
LLVMConstInt(g->builtin_types.entry_usize->type_ref, 0, false),
};
LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, expr_val, indices, 2, "");
gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr,
slice_len_index, "");
LLVMValueRef len_value = LLVMConstInt(g->builtin_types.entry_usize->type_ref,
array_type->data.array.len, false);
gen_store_untyped(g, len_value, len_field_ptr, 0, false);
return cast_instruction->tmp_ptr;
}
}
zig_unreachable();
}
@@ -3815,7 +3838,6 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
} else {
end_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, array_type->data.array.len, false);
}
if (want_runtime_safety) {
add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
if (instruction->end) {