authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-12-30 16:48:14+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-12-30 17:45:09-05:00
log28a8ded95a96b1e2af5d2a73f47db2c967233476
treeac9bc2f2248988c8ebc99d990ea315c0dcc397d9
parentc1ee846c221a43b3bb3f9e427a2077b444435ec7

Resolve more types as needed

Closes #3994

4 files changed, 54 insertions(+), 21 deletions(-)

src/analyze.cpp+3-2
...@@ -6372,10 +6372,11 @@ static Error resolve_pointer_zero_bits(CodeGen *g, ZigType *ty) {...@@ -6372,10 +6372,11 @@ static Error resolve_pointer_zero_bits(CodeGen *g, ZigType *ty) {
63726372
6373 ZigType *elem_type = ty->data.pointer.child_type;6373 ZigType *elem_type = ty->data.pointer.child_type;
63746374
6375 if ((err = type_resolve(g, elem_type, ResolveStatusZeroBitsKnown)))6375 bool has_bits;
6376 if ((err = type_has_bits2(g, elem_type, &has_bits)))
6376 return err;6377 return err;
63776378
6378 if (type_has_bits(elem_type)) {6379 if (has_bits) {
6379 ty->abi_size = g->builtin_types.entry_usize->abi_size;6380 ty->abi_size = g->builtin_types.entry_usize->abi_size;
6380 ty->size_in_bits = g->builtin_types.entry_usize->size_in_bits;6381 ty->size_in_bits = g->builtin_types.entry_usize->size_in_bits;
6381 ty->abi_align = g->builtin_types.entry_usize->abi_align;6382 ty->abi_align = g->builtin_types.entry_usize->abi_align;
src/codegen.cpp+15-4
...@@ -1725,11 +1725,14 @@ static void gen_var_debug_decl(CodeGen *g, ZigVar *var) {...@@ -1725,11 +1725,14 @@ static void gen_var_debug_decl(CodeGen *g, ZigVar *var) {
17251725
1726static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {1726static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {
1727 Error err;1727 Error err;
1728 if ((err = type_resolve(g, instruction->value->type, ResolveStatusZeroBitsKnown))) {1728
1729 bool value_has_bits;
1730 if ((err = type_has_bits2(g, instruction->value->type, &value_has_bits)))
1729 codegen_report_errors_and_exit(g);1731 codegen_report_errors_and_exit(g);
1730 }1732
1731 if (!type_has_bits(instruction->value->type))1733 if (!value_has_bits)
1732 return nullptr;1734 return nullptr;
1735
1733 if (!instruction->llvm_value) {1736 if (!instruction->llvm_value) {
1734 if (instruction->id == IrInstructionIdAwaitGen) {1737 if (instruction->id == IrInstructionIdAwaitGen) {
1735 IrInstructionAwaitGen *await = reinterpret_cast<IrInstructionAwaitGen*>(instruction);1738 IrInstructionAwaitGen *await = reinterpret_cast<IrInstructionAwaitGen*>(instruction);
...@@ -5560,13 +5563,21 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executab...@@ -5560,13 +5563,21 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executab
5560static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *executable,5563static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *executable,
5561 IrInstructionUnwrapErrPayload *instruction)5564 IrInstructionUnwrapErrPayload *instruction)
5562{5565{
5566 Error err;
5567
5563 if (instruction->base.value->special != ConstValSpecialRuntime)5568 if (instruction->base.value->special != ConstValSpecialRuntime)
5564 return nullptr;5569 return nullptr;
55655570
5566 bool want_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base) &&5571 bool want_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base) &&
5567 g->errors_by_index.length > 1;5572 g->errors_by_index.length > 1;
5568 if (!want_safety && !type_has_bits(instruction->base.value->type))5573
5574 bool value_has_bits;
5575 if ((err = type_has_bits2(g, instruction->base.value->type, &value_has_bits)))
5576 codegen_report_errors_and_exit(g);
5577
5578 if (!want_safety && !value_has_bits)
5569 return nullptr;5579 return nullptr;
5580
5570 ZigType *ptr_type = instruction->value->value->type;5581 ZigType *ptr_type = instruction->value->value->type;
5571 assert(ptr_type->id == ZigTypeIdPointer);5582 assert(ptr_type->id == ZigTypeIdPointer);
5572 ZigType *err_union_type = ptr_type->data.pointer.child_type;5583 ZigType *err_union_type = ptr_type->data.pointer.child_type;
src/ir.cpp+21-15
...@@ -12687,9 +12687,10 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so...@@ -12687,9 +12687,10 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so
12687 ZigType *field_type = resolve_union_field_type(ira->codegen, union_field);12687 ZigType *field_type = resolve_union_field_type(ira->codegen, union_field);
12688 if (field_type == nullptr)12688 if (field_type == nullptr)
12689 return ira->codegen->invalid_instruction;12689 return ira->codegen->invalid_instruction;
12690 if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown)))12690 bool has_bits;
12691 if ((err = type_has_bits2(ira->codegen, field_type, &has_bits)))
12691 return ira->codegen->invalid_instruction;12692 return ira->codegen->invalid_instruction;
12692 if (type_has_bits(field_type)) {12693 if (has_bits) {
12693 AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at(i);12694 AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at(i);
12694 add_error_note(ira->codegen, msg, field_node,12695 add_error_note(ira->codegen, msg, field_node,
12695 buf_sprintf("field '%s' has type '%s'",12696 buf_sprintf("field '%s' has type '%s'",
...@@ -13892,10 +13893,10 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -13892,10 +13893,10 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
13892 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,13893 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
13893 actual_type, source_node, !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk)13894 actual_type, source_node, !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk)
13894 {13895 {
13895 if ((err = type_resolve(ira->codegen, actual_type, ResolveStatusZeroBitsKnown))) {13896 bool has_bits;
13897 if ((err = type_has_bits2(ira->codegen, actual_type, &has_bits)))
13896 return ira->codegen->invalid_instruction;13898 return ira->codegen->invalid_instruction;
13897 }13899 if (!has_bits) {
13898 if (!type_has_bits(actual_type)) {
13899 return ir_get_ref(ira, source_instr, value, false, false);13900 return ir_get_ref(ira, source_instr, value, false, false);
13900 }13901 }
13901 }13902 }
...@@ -17163,10 +17164,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe...@@ -17163,10 +17164,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
17163 if (is_comptime)17164 if (is_comptime)
17164 return nullptr;17165 return nullptr;
17165 }17166 }
17166 if ((err = type_resolve(ira->codegen, ira->explicit_return_type, ResolveStatusZeroBitsKnown))) {17167 bool has_bits;
17168 if ((err = type_has_bits2(ira->codegen, ira->explicit_return_type, &has_bits)))
17167 return ira->codegen->invalid_instruction;17169 return ira->codegen->invalid_instruction;
17168 }17170 if (!has_bits || !handle_is_ptr(ira->explicit_return_type)) {
17169 if (!type_has_bits(ira->explicit_return_type) || !handle_is_ptr(ira->explicit_return_type)) {
17170 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);17171 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
17171 if (fn_entry == nullptr || fn_entry->inferred_async_node == nullptr) {17172 if (fn_entry == nullptr || fn_entry->inferred_async_node == nullptr) {
17172 return nullptr;17173 return nullptr;
...@@ -26082,6 +26083,7 @@ static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruct...@@ -26082,6 +26083,7 @@ static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruct
26082 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type,26083 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type,
26083 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,26084 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
26084 PtrLenSingle, 0, 0, 0, false);26085 PtrLenSingle, 0, 0, 0, false);
26086
26085 if (instr_is_comptime(base_ptr)) {26087 if (instr_is_comptime(base_ptr)) {
26086 ZigValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad);26088 ZigValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad);
26087 if (!ptr_val)26089 if (!ptr_val)
...@@ -27136,15 +27138,16 @@ static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstru...@@ -27136,15 +27138,16 @@ static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstru
27136 return ira->codegen->invalid_instruction;27138 return ira->codegen->invalid_instruction;
27137 }27139 }
2713827140
27139 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown)))27141 bool has_bits;
27142 if ((err = type_has_bits2(ira->codegen, dest_type, &has_bits)))
27140 return ira->codegen->invalid_instruction;27143 return ira->codegen->invalid_instruction;
27141 if (!type_has_bits(dest_type)) {27144
27145 if (!has_bits) {
27142 ir_add_error(ira, dest_type_value,27146 ir_add_error(ira, dest_type_value,
27143 buf_sprintf("type '%s' has 0 bits and cannot store information", buf_ptr(&dest_type->name)));27147 buf_sprintf("type '%s' has 0 bits and cannot store information", buf_ptr(&dest_type->name)));
27144 return ira->codegen->invalid_instruction;27148 return ira->codegen->invalid_instruction;
27145 }27149 }
2714627150
27147
27148 IrInstruction *target = instruction->target->child;27151 IrInstruction *target = instruction->target->child;
27149 if (type_is_invalid(target->value->type))27152 if (type_is_invalid(target->value->type))
27150 return ira->codegen->invalid_instruction;27153 return ira->codegen->invalid_instruction;
...@@ -27182,9 +27185,11 @@ static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstru...@@ -27182,9 +27185,11 @@ static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstru
27182 return ira->codegen->invalid_instruction;27185 return ira->codegen->invalid_instruction;
27183 }27186 }
2718427187
27185 if ((err = type_resolve(ira->codegen, target->value->type, ResolveStatusZeroBitsKnown)))27188 bool has_bits;
27189 if ((err = type_has_bits2(ira->codegen, target->value->type, &has_bits)))
27186 return ira->codegen->invalid_instruction;27190 return ira->codegen->invalid_instruction;
27187 if (!type_has_bits(target->value->type)) {27191
27192 if (!has_bits) {
27188 ir_add_error(ira, target,27193 ir_add_error(ira, target,
27189 buf_sprintf("pointer to size 0 type has no address"));27194 buf_sprintf("pointer to size 0 type has no address"));
27190 return ira->codegen->invalid_instruction;27195 return ira->codegen->invalid_instruction;
...@@ -29067,9 +29072,10 @@ static ZigType *ir_resolve_lazy_fn_type(IrAnalyze *ira, AstNode *source_node, La...@@ -29067,9 +29072,10 @@ static ZigType *ir_resolve_lazy_fn_type(IrAnalyze *ira, AstNode *source_node, La
29067 break;29072 break;
29068 }29073 }
29069 if (!calling_convention_allows_zig_types(fn_type_id.cc)) {29074 if (!calling_convention_allows_zig_types(fn_type_id.cc)) {
29070 if ((err = type_resolve(ira->codegen, param_type, ResolveStatusZeroBitsKnown)))29075 bool has_bits;
29076 if ((err = type_has_bits2(ira->codegen, param_type, &has_bits)))
29071 return nullptr;29077 return nullptr;
29072 if (!type_has_bits(param_type)) {29078 if (!has_bits) {
29073 ir_add_error(ira, param_type_inst,29079 ir_add_error(ira, param_type_inst,
29074 buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'",29080 buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'",
29075 buf_ptr(&param_type->name), calling_convention_name(fn_type_id.cc)));29081 buf_ptr(&param_type->name), calling_convention_name(fn_type_id.cc)));
test/stage1/behavior/error.zig+15
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1const std = @import("std");1const std = @import("std");
2const expect = std.testing.expect;2const expect = std.testing.expect;
3const expectError = std.testing.expectError;3const expectError = std.testing.expectError;
4const expectEqual = std.testing.expectEqual;
4const mem = std.mem;5const mem = std.mem;
5const builtin = @import("builtin");6const builtin = @import("builtin");
67
...@@ -427,3 +428,17 @@ test "return result loc as peer result loc in inferred error set function" {...@@ -427,3 +428,17 @@ test "return result loc as peer result loc in inferred error set function" {
427 S.doTheTest();428 S.doTheTest();
428 comptime S.doTheTest();429 comptime S.doTheTest();
429}430}
431
432test "error payload type is correctly resolved" {
433 const MyIntWrapper = struct {
434 const Self = @This();
435
436 x: i32,
437
438 pub fn create() anyerror!Self {
439 return Self{ .x = 42 };
440 }
441 };
442
443 expectEqual(MyIntWrapper{ .x = 42 }, try MyIntWrapper.create());
444}