| author | |
| committer | |
| log | 287d3c37e1f53b6f0a0b29753b68254001194e62 |
| tree | 3d9a4db2edfc3d2ec1df5c9856b5d1ddf2d562ac |
| parent | 8710fdbf39c793027f332bd00efe70edaa86d91c |
| signature | Commit is signed but in an unrecognized format. |
by un-special-casing 0 bit types in result locations3 files changed, 55 insertions(+), 32 deletions(-)
src/analyze.cpp+19-1| ... | @@ -5700,6 +5700,9 @@ ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry) { | ... | @@ -5700,6 +5700,9 @@ ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry) { |
| 5700 | assert(field_type != nullptr); | 5700 | assert(field_type != nullptr); |
| 5701 | result->data.x_struct.fields[i] = get_the_one_possible_value(g, field_type); | 5701 | result->data.x_struct.fields[i] = get_the_one_possible_value(g, field_type); |
| 5702 | } | 5702 | } |
| 5703 | } else if (result->type->id == ZigTypeIdPointer) { | ||
| 5704 | result->data.x_ptr.special = ConstPtrSpecialRef; | ||
| 5705 | result->data.x_ptr.data.ref.pointee = get_the_one_possible_value(g, result->type->data.pointer.child_type); | ||
| 5703 | } | 5706 | } |
| 5704 | g->one_possible_values.put(type_entry, result); | 5707 | g->one_possible_values.put(type_entry, result); |
| 5705 | return result; | 5708 | return result; |
| ... | @@ -9471,7 +9474,11 @@ static void dump_value_indent(ZigValue *val, int indent) { | ... | @@ -9471,7 +9474,11 @@ static void dump_value_indent(ZigValue *val, int indent) { |
| 9471 | fprintf(stderr, " "); | 9474 | fprintf(stderr, " "); |
| 9472 | } | 9475 | } |
| 9473 | fprintf(stderr, "%s: ", buf_ptr(val->type->data.structure.fields[i]->name)); | 9476 | fprintf(stderr, "%s: ", buf_ptr(val->type->data.structure.fields[i]->name)); |
| 9474 | dump_value_indent(val->data.x_struct.fields[i], 1); | 9477 | if (val->data.x_struct.fields == nullptr) { |
| 9478 | fprintf(stderr, "<null>\n"); | ||
| 9479 | } else { | ||
| 9480 | dump_value_indent(val->data.x_struct.fields[i], 1); | ||
| 9481 | } | ||
| 9475 | } | 9482 | } |
| 9476 | for (int i = 0; i < indent; i += 1) { | 9483 | for (int i = 0; i < indent; i += 1) { |
| 9477 | fprintf(stderr, " "); | 9484 | fprintf(stderr, " "); |
| ... | @@ -9505,6 +9512,9 @@ static void dump_value_indent(ZigValue *val, int indent) { | ... | @@ -9505,6 +9512,9 @@ static void dump_value_indent(ZigValue *val, int indent) { |
| 9505 | 9512 | ||
| 9506 | case ZigTypeIdPointer: | 9513 | case ZigTypeIdPointer: |
| 9507 | switch (val->data.x_ptr.special) { | 9514 | switch (val->data.x_ptr.special) { |
| 9515 | case ConstPtrSpecialInvalid: | ||
| 9516 | fprintf(stderr, "<!invalid ptr!>\n"); | ||
| 9517 | return; | ||
| 9508 | case ConstPtrSpecialRef: | 9518 | case ConstPtrSpecialRef: |
| 9509 | fprintf(stderr, "<ref\n"); | 9519 | fprintf(stderr, "<ref\n"); |
| 9510 | dump_value_indent(val->data.x_ptr.data.ref.pointee, indent + 1); | 9520 | dump_value_indent(val->data.x_ptr.data.ref.pointee, indent + 1); |
| ... | @@ -9526,6 +9536,14 @@ static void dump_value_indent(ZigValue *val, int indent) { | ... | @@ -9526,6 +9536,14 @@ static void dump_value_indent(ZigValue *val, int indent) { |
| 9526 | } | 9536 | } |
| 9527 | break; | 9537 | break; |
| 9528 | } | 9538 | } |
| 9539 | case ConstPtrSpecialBaseOptionalPayload: { | ||
| 9540 | ZigValue *optional_val = val->data.x_ptr.data.base_optional_payload.optional_val; | ||
| 9541 | fprintf(stderr, "<optional %p payload\n", optional_val); | ||
| 9542 | if (optional_val != nullptr) { | ||
| 9543 | dump_value_indent(optional_val, indent + 1); | ||
| 9544 | } | ||
| 9545 | break; | ||
| 9546 | } | ||
| 9529 | default: | 9547 | default: |
| 9530 | fprintf(stderr, "TODO dump more pointer things\n"); | 9548 | fprintf(stderr, "TODO dump more pointer things\n"); |
| 9531 | } | 9549 | } |
src/ir.cpp+14-31| ... | @@ -18576,7 +18576,6 @@ static IrInstGen *ir_resolve_result(IrAnalyze *ira, IrInst *suspend_source_instr | ... | @@ -18576,7 +18576,6 @@ static IrInstGen *ir_resolve_result(IrAnalyze *ira, IrInst *suspend_source_instr |
| 18576 | ResultLoc *result_loc_pass1, ZigType *value_type, IrInstGen *value, bool force_runtime, | 18576 | ResultLoc *result_loc_pass1, ZigType *value_type, IrInstGen *value, bool force_runtime, |
| 18577 | bool allow_discard) | 18577 | bool allow_discard) |
| 18578 | { | 18578 | { |
| 18579 | Error err; | ||
| 18580 | if (!allow_discard && result_loc_is_discard(result_loc_pass1)) { | 18579 | if (!allow_discard && result_loc_is_discard(result_loc_pass1)) { |
| 18581 | result_loc_pass1 = no_result_loc(); | 18580 | result_loc_pass1 = no_result_loc(); |
| 18582 | } | 18581 | } |
| ... | @@ -18672,32 +18671,22 @@ static IrInstGen *ir_resolve_result(IrAnalyze *ira, IrInst *suspend_source_instr | ... | @@ -18672,32 +18671,22 @@ static IrInstGen *ir_resolve_result(IrAnalyze *ira, IrInst *suspend_source_instr |
| 18672 | { | 18671 | { |
| 18673 | bool same_comptime_repr = types_have_same_zig_comptime_repr(ira->codegen, actual_elem_type, value_type); | 18672 | bool same_comptime_repr = types_have_same_zig_comptime_repr(ira->codegen, actual_elem_type, value_type); |
| 18674 | if (!same_comptime_repr) { | 18673 | if (!same_comptime_repr) { |
| 18675 | bool has_bits; | 18674 | result_loc_pass1->written = false; |
| 18676 | if ((err = type_has_bits2(ira->codegen, value_type, &has_bits))) | 18675 | return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true); |
| 18677 | return ira->codegen->invalid_inst_gen; | ||
| 18678 | if (has_bits) { | ||
| 18679 | result_loc_pass1->written = false; | ||
| 18680 | return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true); | ||
| 18681 | } | ||
| 18682 | } | 18676 | } |
| 18683 | } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion) { | 18677 | } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion) { |
| 18684 | bool has_bits; | 18678 | if (value_type->id == ZigTypeIdErrorSet) { |
| 18685 | if ((err = type_has_bits2(ira->codegen, value_type, &has_bits))) | 18679 | return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, true); |
| 18686 | return ira->codegen->invalid_inst_gen; | 18680 | } else { |
| 18687 | if (has_bits) { | 18681 | IrInstGen *unwrapped_err_ptr = ir_analyze_unwrap_error_payload(ira, suspend_source_instr, |
| 18688 | if (value_type->id == ZigTypeIdErrorSet) { | 18682 | result_loc, false, true); |
| 18689 | return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, true); | 18683 | ZigType *actual_payload_type = actual_elem_type->data.error_union.payload_type; |
| 18684 | if (actual_payload_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional && | ||
| 18685 | value_type->id != ZigTypeIdNull) | ||
| 18686 | { | ||
| 18687 | return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, unwrapped_err_ptr, false, true); | ||
| 18690 | } else { | 18688 | } else { |
| 18691 | IrInstGen *unwrapped_err_ptr = ir_analyze_unwrap_error_payload(ira, suspend_source_instr, | 18689 | return unwrapped_err_ptr; |
| 18692 | result_loc, false, true); | ||
| 18693 | ZigType *actual_payload_type = actual_elem_type->data.error_union.payload_type; | ||
| 18694 | if (actual_payload_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional && | ||
| 18695 | value_type->id != ZigTypeIdNull) | ||
| 18696 | { | ||
| 18697 | return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, unwrapped_err_ptr, false, true); | ||
| 18698 | } else { | ||
| 18699 | return unwrapped_err_ptr; | ||
| 18700 | } | ||
| 18701 | } | 18690 | } |
| 18702 | } | 18691 | } |
| 18703 | } | 18692 | } |
| ... | @@ -22215,14 +22204,8 @@ static IrInstGen *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInst* sou | ... | @@ -22215,14 +22204,8 @@ static IrInstGen *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInst* sou |
| 22215 | } | 22204 | } |
| 22216 | break; | 22205 | break; |
| 22217 | case OnePossibleValueYes: { | 22206 | case OnePossibleValueYes: { |
| 22218 | ZigValue *pointee = create_const_vals(1); | ||
| 22219 | pointee->special = ConstValSpecialStatic; | ||
| 22220 | pointee->type = child_type; | ||
| 22221 | pointee->parent.id = ConstParentIdOptionalPayload; | ||
| 22222 | pointee->parent.data.p_optional_payload.optional_val = optional_val; | ||
| 22223 | |||
| 22224 | optional_val->special = ConstValSpecialStatic; | 22207 | optional_val->special = ConstValSpecialStatic; |
| 22225 | optional_val->data.x_optional = pointee; | 22208 | optional_val->data.x_optional = get_the_one_possible_value(ira->codegen, child_type); |
| 22226 | break; | 22209 | break; |
| 22227 | } | 22210 | } |
| 22228 | } | 22211 | } |
test/stage1/behavior/optional.zig+22| ... | @@ -153,3 +153,25 @@ test "optional with void type" { | ... | @@ -153,3 +153,25 @@ test "optional with void type" { |
| 153 | var x = Foo{ .x = null }; | 153 | var x = Foo{ .x = null }; |
| 154 | expect(x.x == null); | 154 | expect(x.x == null); |
| 155 | } | 155 | } |
| 156 | |||
| 157 | test "0-bit child type coerced to optional return ptr result location" { | ||
| 158 | const S = struct { | ||
| 159 | fn doTheTest() void { | ||
| 160 | var y = Foo{}; | ||
| 161 | var z = y.thing(); | ||
| 162 | expect(z != null); | ||
| 163 | } | ||
| 164 | |||
| 165 | const Foo = struct { | ||
| 166 | pub const Bar = struct { | ||
| 167 | field: *Foo, | ||
| 168 | }; | ||
| 169 | |||
| 170 | pub fn thing(self: *Foo) ?Bar { | ||
| 171 | return Bar{ .field = self }; | ||
| 172 | } | ||
| 173 | }; | ||
| 174 | }; | ||
| 175 | S.doTheTest(); | ||
| 176 | comptime S.doTheTest(); | ||
| 177 | } |