Skip to content

Commit

Permalink
Resolve more types as needed
Browse files Browse the repository at this point in the history
  • Loading branch information
LemonBoy committed Dec 30, 2019
1 parent c70a673 commit fd699d0
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 21 deletions.
5 changes: 3 additions & 2 deletions src/analyze.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6372,10 +6372,11 @@ static Error resolve_pointer_zero_bits(CodeGen *g, ZigType *ty) {

ZigType *elem_type = ty->data.pointer.child_type;

if ((err = type_resolve(g, elem_type, ResolveStatusZeroBitsKnown)))
bool has_bits;
if ((err = type_has_bits2(g, elem_type, &has_bits)))
return err;

if (type_has_bits(elem_type)) {
if (has_bits) {
ty->abi_size = g->builtin_types.entry_usize->abi_size;
ty->size_in_bits = g->builtin_types.entry_usize->size_in_bits;
ty->abi_align = g->builtin_types.entry_usize->abi_align;
Expand Down
19 changes: 15 additions & 4 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1725,11 +1725,14 @@ static void gen_var_debug_decl(CodeGen *g, ZigVar *var) {

static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {
Error err;
if ((err = type_resolve(g, instruction->value->type, ResolveStatusZeroBitsKnown))) {

bool value_has_bits;
if ((err = type_has_bits2(g, instruction->value->type, &value_has_bits)))
codegen_report_errors_and_exit(g);
}
if (!type_has_bits(instruction->value->type))

if (!value_has_bits)
return nullptr;

if (!instruction->llvm_value) {
if (instruction->id == IrInstructionIdAwaitGen) {
IrInstructionAwaitGen *await = reinterpret_cast<IrInstructionAwaitGen*>(instruction);
Expand Down Expand Up @@ -5560,13 +5563,21 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executab
static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *executable,
IrInstructionUnwrapErrPayload *instruction)
{
Error err;

if (instruction->base.value->special != ConstValSpecialRuntime)
return nullptr;

bool want_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base) &&
g->errors_by_index.length > 1;
if (!want_safety && !type_has_bits(instruction->base.value->type))

bool value_has_bits;
if ((err = type_has_bits2(g, instruction->base.value->type, &value_has_bits)))
codegen_report_errors_and_exit(g);

if (!want_safety && !value_has_bits)
return nullptr;

ZigType *ptr_type = instruction->value->value->type;
assert(ptr_type->id == ZigTypeIdPointer);
ZigType *err_union_type = ptr_type->data.pointer.child_type;
Expand Down
36 changes: 21 additions & 15 deletions src/ir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12687,9 +12687,10 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so
ZigType *field_type = resolve_union_field_type(ira->codegen, union_field);
if (field_type == nullptr)
return ira->codegen->invalid_instruction;
if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown)))
bool has_bits;
if ((err = type_has_bits2(ira->codegen, field_type, &has_bits)))
return ira->codegen->invalid_instruction;
if (type_has_bits(field_type)) {
if (has_bits) {
AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at(i);
add_error_note(ira->codegen, msg, field_node,
buf_sprintf("field '%s' has type '%s'",
Expand Down Expand Up @@ -13892,10 +13893,10 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
actual_type, source_node, !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk)
{
if ((err = type_resolve(ira->codegen, actual_type, ResolveStatusZeroBitsKnown))) {
bool has_bits;
if ((err = type_has_bits2(ira->codegen, actual_type, &has_bits)))
return ira->codegen->invalid_instruction;
}
if (!type_has_bits(actual_type)) {
if (!has_bits) {
return ir_get_ref(ira, source_instr, value, false, false);
}
}
Expand Down Expand Up @@ -17163,10 +17164,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
if (is_comptime)
return nullptr;
}
if ((err = type_resolve(ira->codegen, ira->explicit_return_type, ResolveStatusZeroBitsKnown))) {
bool has_bits;
if ((err = type_has_bits2(ira->codegen, ira->explicit_return_type, &has_bits)))
return ira->codegen->invalid_instruction;
}
if (!type_has_bits(ira->explicit_return_type) || !handle_is_ptr(ira->explicit_return_type)) {
if (!has_bits || !handle_is_ptr(ira->explicit_return_type)) {
ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
if (fn_entry == nullptr || fn_entry->inferred_async_node == nullptr) {
return nullptr;
Expand Down Expand Up @@ -26082,6 +26083,7 @@ static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruct
ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type,
ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
PtrLenSingle, 0, 0, 0, false);

if (instr_is_comptime(base_ptr)) {
ZigValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad);
if (!ptr_val)
Expand Down Expand Up @@ -27136,15 +27138,16 @@ static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstru
return ira->codegen->invalid_instruction;
}

if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown)))
bool has_bits;
if ((err = type_has_bits2(ira->codegen, dest_type, &has_bits)))
return ira->codegen->invalid_instruction;
if (!type_has_bits(dest_type)) {

if (!has_bits) {
ir_add_error(ira, dest_type_value,
buf_sprintf("type '%s' has 0 bits and cannot store information", buf_ptr(&dest_type->name)));
return ira->codegen->invalid_instruction;
}


IrInstruction *target = instruction->target->child;
if (type_is_invalid(target->value->type))
return ira->codegen->invalid_instruction;
Expand Down Expand Up @@ -27182,9 +27185,11 @@ static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstru
return ira->codegen->invalid_instruction;
}

if ((err = type_resolve(ira->codegen, target->value->type, ResolveStatusZeroBitsKnown)))
bool has_bits;
if ((err = type_has_bits2(ira->codegen, target->value->type, &has_bits)))
return ira->codegen->invalid_instruction;
if (!type_has_bits(target->value->type)) {

if (!has_bits) {
ir_add_error(ira, target,
buf_sprintf("pointer to size 0 type has no address"));
return ira->codegen->invalid_instruction;
Expand Down Expand Up @@ -29067,9 +29072,10 @@ static ZigType *ir_resolve_lazy_fn_type(IrAnalyze *ira, AstNode *source_node, La
break;
}
if (!calling_convention_allows_zig_types(fn_type_id.cc)) {
if ((err = type_resolve(ira->codegen, param_type, ResolveStatusZeroBitsKnown)))
bool has_bits;
if ((err = type_has_bits2(ira->codegen, param_type, &has_bits)))
return nullptr;
if (!type_has_bits(param_type)) {
if (!has_bits) {
ir_add_error(ira, param_type_inst,
buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'",
buf_ptr(&param_type->name), calling_convention_name(fn_type_id.cc)));
Expand Down
15 changes: 15 additions & 0 deletions test/stage1/behavior/error.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const std = @import("std");
const expect = std.testing.expect;
const expectError = std.testing.expectError;
const expectEqual = std.testing.expectEqual;
const mem = std.mem;
const builtin = @import("builtin");

Expand Down Expand Up @@ -427,3 +428,17 @@ test "return result loc as peer result loc in inferred error set function" {
S.doTheTest();
comptime S.doTheTest();
}

test "error payload type is correctly resolved" {
const MyIntWrapper = struct {
const Self = @This();

x: i32,

pub fn create() anyerror!Self {
return Self{ .x = 42 };
}
};

expectEqual(MyIntWrapper{ .x = 42 }, try MyIntWrapper.create());
}

0 comments on commit fd699d0

Please sign in to comment.