authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-28 00:02:53-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-28 00:02:53-05:00
logbcdb3a90066148dc5a91d176a8fc7f5d9c7487b1
tree727cee5fbbf65e81aff41b4e24b65fc065960275
parentbf3ac6615051143a9ef41180cd74e88de5dd573d
signaturelock-open Commit is signed but in an unrecognized format.

more progress


5 files changed, 126 insertions(+), 33 deletions(-)

src/ir.cpp+51-21
...@@ -41,6 +41,9 @@ struct IrAnalyze {...@@ -41,6 +41,9 @@ struct IrAnalyze {
41 ZigList<IrInstruction *> src_implicit_return_type_list;41 ZigList<IrInstruction *> src_implicit_return_type_list;
42 ZigList<IrSuspendPosition> resume_stack;42 ZigList<IrSuspendPosition> resume_stack;
43 IrBasicBlock *const_predecessor_bb;43 IrBasicBlock *const_predecessor_bb;
44
45 // For the purpose of using in a debugger
46 void dump();
44};47};
4548
46enum ConstCastResultId {49enum ConstCastResultId {
...@@ -350,6 +353,7 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte...@@ -350,6 +353,7 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte
350 case ZigTypeIdErrorSet:353 case ZigTypeIdErrorSet:
351 case ZigTypeIdOpaque:354 case ZigTypeIdOpaque:
352 case ZigTypeIdAnyFrame:355 case ZigTypeIdAnyFrame:
356 case ZigTypeIdFn:
353 return true;357 return true;
354 case ZigTypeIdFloat:358 case ZigTypeIdFloat:
355 return expected->data.floating.bit_count == actual->data.floating.bit_count;359 return expected->data.floating.bit_count == actual->data.floating.bit_count;
...@@ -361,7 +365,6 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte...@@ -361,7 +365,6 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte
361 case ZigTypeIdErrorUnion:365 case ZigTypeIdErrorUnion:
362 case ZigTypeIdEnum:366 case ZigTypeIdEnum:
363 case ZigTypeIdUnion:367 case ZigTypeIdUnion:
364 case ZigTypeIdFn:
365 case ZigTypeIdArgTuple:368 case ZigTypeIdArgTuple:
366 case ZigTypeIdVector:369 case ZigTypeIdVector:
367 case ZigTypeIdFnFrame:370 case ZigTypeIdFnFrame:
...@@ -3941,6 +3944,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode...@@ -3941,6 +3944,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
3941 scope_block->peer_parent = allocate<ResultLocPeerParent>(1, "ResultLocPeerParent");3944 scope_block->peer_parent = allocate<ResultLocPeerParent>(1, "ResultLocPeerParent");
3942 scope_block->peer_parent->base.id = ResultLocIdPeerParent;3945 scope_block->peer_parent->base.id = ResultLocIdPeerParent;
3943 scope_block->peer_parent->base.source_instruction = scope_block->is_comptime;3946 scope_block->peer_parent->base.source_instruction = scope_block->is_comptime;
3947 scope_block->peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const;
3944 scope_block->peer_parent->end_bb = scope_block->end_block;3948 scope_block->peer_parent->end_bb = scope_block->end_block;
3945 scope_block->peer_parent->is_comptime = scope_block->is_comptime;3949 scope_block->peer_parent->is_comptime = scope_block->is_comptime;
3946 scope_block->peer_parent->parent = result_loc;3950 scope_block->peer_parent->parent = result_loc;
...@@ -4195,6 +4199,7 @@ static ResultLocPeerParent *ir_build_result_peers(IrBuilder *irb, IrInstruction...@@ -4195,6 +4199,7 @@ static ResultLocPeerParent *ir_build_result_peers(IrBuilder *irb, IrInstruction
4195 ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1);4199 ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1);
4196 peer_parent->base.id = ResultLocIdPeerParent;4200 peer_parent->base.id = ResultLocIdPeerParent;
4197 peer_parent->base.source_instruction = cond_br_inst;4201 peer_parent->base.source_instruction = cond_br_inst;
4202 peer_parent->base.allow_write_through_const = parent->allow_write_through_const;
4198 peer_parent->end_bb = end_block;4203 peer_parent->end_bb = end_block;
4199 peer_parent->is_comptime = is_comptime;4204 peer_parent->is_comptime = is_comptime;
4200 peer_parent->parent = parent;4205 peer_parent->parent = parent;
...@@ -6388,6 +6393,7 @@ static ResultLocVar *ir_build_var_result_loc(IrBuilder *irb, IrInstruction *allo...@@ -6388,6 +6393,7 @@ static ResultLocVar *ir_build_var_result_loc(IrBuilder *irb, IrInstruction *allo
6388 ResultLocVar *result_loc_var = allocate<ResultLocVar>(1);6393 ResultLocVar *result_loc_var = allocate<ResultLocVar>(1);
6389 result_loc_var->base.id = ResultLocIdVar;6394 result_loc_var->base.id = ResultLocIdVar;
6390 result_loc_var->base.source_instruction = alloca;6395 result_loc_var->base.source_instruction = alloca;
6396 result_loc_var->base.allow_write_through_const = true;
6391 result_loc_var->var = var;6397 result_loc_var->var = var;
63926398
6393 ir_build_reset_result(irb, alloca->scope, alloca->source_node, &result_loc_var->base);6399 ir_build_reset_result(irb, alloca->scope, alloca->source_node, &result_loc_var->base);
...@@ -6401,6 +6407,7 @@ static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *de...@@ -6401,6 +6407,7 @@ static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *de
6401 ResultLocCast *result_loc_cast = allocate<ResultLocCast>(1);6407 ResultLocCast *result_loc_cast = allocate<ResultLocCast>(1);
6402 result_loc_cast->base.id = ResultLocIdCast;6408 result_loc_cast->base.id = ResultLocIdCast;
6403 result_loc_cast->base.source_instruction = dest_type;6409 result_loc_cast->base.source_instruction = dest_type;
6410 result_loc_cast->base.allow_write_through_const = parent_result_loc->allow_write_through_const;
6404 ir_ref_instruction(dest_type, irb->current_basic_block);6411 ir_ref_instruction(dest_type, irb->current_basic_block);
6405 result_loc_cast->parent = parent_result_loc;6412 result_loc_cast->parent = parent_result_loc;
64066413
...@@ -7581,6 +7588,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -7581,6 +7588,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
75817588
7582 ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1);7589 ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1);
7583 peer_parent->base.id = ResultLocIdPeerParent;7590 peer_parent->base.id = ResultLocIdPeerParent;
7591 peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const;
7584 peer_parent->end_bb = end_block;7592 peer_parent->end_bb = end_block;
7585 peer_parent->is_comptime = is_comptime;7593 peer_parent->is_comptime = is_comptime;
7586 peer_parent->parent = result_loc;7594 peer_parent->parent = result_loc;
...@@ -13396,16 +13404,24 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -13396,16 +13404,24 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
13396 return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type);13404 return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type);
13397 }13405 }
1339813406
13399 // T to ?E!T13407 // T to ?U, where T implicitly casts to U
13400 if (wanted_type->id == ZigTypeIdOptional && wanted_type->data.maybe.child_type->id == ZigTypeIdErrorUnion &&13408 if (wanted_type->id == ZigTypeIdOptional && actual_type->id != ZigTypeIdOptional) {
13401 actual_type->id != ZigTypeIdOptional)
13402 {
13403 IrInstruction *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.maybe.child_type);13409 IrInstruction *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.maybe.child_type);
13404 if (type_is_invalid(cast1->value->type))13410 if (type_is_invalid(cast1->value->type))
13405 return ira->codegen->invalid_instruction;13411 return ira->codegen->invalid_instruction;
13406 return ir_implicit_cast2(ira, source_instr, cast1, wanted_type);13412 return ir_implicit_cast2(ira, source_instr, cast1, wanted_type);
13407 }13413 }
1340813414
13415 // T to E!U, where T implicitly casts to U
13416 if (wanted_type->id == ZigTypeIdErrorUnion && actual_type->id != ZigTypeIdErrorUnion &&
13417 actual_type->id != ZigTypeIdErrorSet)
13418 {
13419 IrInstruction *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.error_union.payload_type);
13420 if (type_is_invalid(cast1->value->type))
13421 return ira->codegen->invalid_instruction;
13422 return ir_implicit_cast2(ira, source_instr, cast1, wanted_type);
13423 }
13424
13409 ErrorMsg *parent_msg = ir_add_error_node(ira, source_instr->source_node,13425 ErrorMsg *parent_msg = ir_add_error_node(ira, source_instr->source_node,
13410 buf_sprintf("expected type '%s', found '%s'",13426 buf_sprintf("expected type '%s', found '%s'",
13411 buf_ptr(&wanted_type->name),13427 buf_ptr(&wanted_type->name),
...@@ -16046,7 +16062,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe...@@ -16046,7 +16062,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
16046 bool force_comptime;16062 bool force_comptime;
16047 if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime))16063 if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime))
16048 return ira->codegen->invalid_instruction;16064 return ira->codegen->invalid_instruction;
16049 bool is_comptime = force_comptime || (value != nullptr &&16065 bool is_comptime = force_comptime || (!force_runtime && value != nullptr &&
16050 value->value->special != ConstValSpecialRuntime && result_loc_var->var->gen_is_const);16066 value->value->special != ConstValSpecialRuntime && result_loc_var->var->gen_is_const);
1605116067
16052 if (alloca_src->base.child == nullptr || is_comptime) {16068 if (alloca_src->base.child == nullptr || is_comptime) {
...@@ -16064,7 +16080,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe...@@ -16064,7 +16080,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
16064 alloca_gen = ir_analyze_alloca(ira, result_loc->source_instruction, value_type, align,16080 alloca_gen = ir_analyze_alloca(ira, result_loc->source_instruction, value_type, align,
16065 alloca_src->name_hint, force_comptime);16081 alloca_src->name_hint, force_comptime);
16066 }16082 }
16067 if (alloca_src->base.child != nullptr) {16083 if (alloca_src->base.child != nullptr && !result_loc->written) {
16068 alloca_src->base.child->ref_count = 0;16084 alloca_src->base.child->ref_count = 0;
16069 }16085 }
16070 alloca_src->base.child = alloca_gen;16086 alloca_src->base.child = alloca_gen;
...@@ -16079,6 +16095,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe...@@ -16079,6 +16095,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
16079 return result_loc->resolved_loc;16095 return result_loc->resolved_loc;
16080 }16096 }
16081 case ResultLocIdReturn: {16097 case ResultLocIdReturn: {
16098 if (value != nullptr) {
16099 reinterpret_cast<ResultLocReturn *>(result_loc)->implicit_return_type_done = true;
16100 ira->src_implicit_return_type_list.append(value);
16101 }
16082 if (!non_null_comptime) {16102 if (!non_null_comptime) {
16083 bool is_comptime = value != nullptr && value->value->special != ConstValSpecialRuntime;16103 bool is_comptime = value != nullptr && value->value->special != ConstValSpecialRuntime;
16084 if (is_comptime)16104 if (is_comptime)
...@@ -16121,10 +16141,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe...@@ -16121,10 +16141,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
16121 return result_loc->resolved_loc;16141 return result_loc->resolved_loc;
16122 }16142 }
1612316143
16124 bool is_comptime;16144 bool is_condition_comptime;
16125 if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_comptime))16145 if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_condition_comptime))
16126 return ira->codegen->invalid_instruction;16146 return ira->codegen->invalid_instruction;
16127 if (is_comptime) {16147 if (is_condition_comptime) {
16128 peer_parent->skipped = true;16148 peer_parent->skipped = true;
16129 if (non_null_comptime) {16149 if (non_null_comptime) {
16130 return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,16150 return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,
...@@ -16136,17 +16156,18 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe...@@ -16136,17 +16156,18 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
16136 if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type)))16156 if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type)))
16137 return ira->codegen->invalid_instruction;16157 return ira->codegen->invalid_instruction;
16138 if (peer_parent_has_type) {16158 if (peer_parent_has_type) {
16139 if (peer_parent->parent->id == ResultLocIdReturn && value != nullptr) {
16140 reinterpret_cast<ResultLocReturn *>(peer_parent->parent)->implicit_return_type_done = true;
16141 ira->src_implicit_return_type_list.append(value);
16142 }
16143 peer_parent->skipped = true;16159 peer_parent->skipped = true;
16144 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,16160 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,
16145 value_type, value, force_runtime || !is_comptime, true, true);16161 value_type, value, force_runtime || !is_condition_comptime, true, true);
16146 if (parent_result_loc != nullptr) {16162 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) ||
16147 peer_parent->parent->written = true;16163 parent_result_loc->value->type->id == ZigTypeIdUnreachable)
16164 {
16165 return parent_result_loc;
16148 }16166 }
16149 return parent_result_loc;16167 peer_parent->parent->written = true;
16168 result_loc->written = true;
16169 result_loc->resolved_loc = parent_result_loc;
16170 return result_loc->resolved_loc;
16150 }16171 }
1615116172
16152 if (peer_parent->resolved_type == nullptr) {16173 if (peer_parent->resolved_type == nullptr) {
...@@ -16168,14 +16189,14 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe...@@ -16168,14 +16189,14 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
16168 {16189 {
16169 return parent_result_loc;16190 return parent_result_loc;
16170 }16191 }
16171 // because is_comptime is false, we mark this a runtime pointer16192 // because is_condition_comptime is false, we mark this a runtime pointer
16172 parent_result_loc->value->special = ConstValSpecialRuntime;16193 parent_result_loc->value->special = ConstValSpecialRuntime;
16173 result_loc->written = true;16194 result_loc->written = true;
16174 result_loc->resolved_loc = parent_result_loc;16195 result_loc->resolved_loc = parent_result_loc;
16175 return result_loc->resolved_loc;16196 return result_loc->resolved_loc;
16176 }16197 }
16177 case ResultLocIdCast: {16198 case ResultLocIdCast: {
16178 if (value != nullptr && value->value->special != ConstValSpecialRuntime)16199 if (value != nullptr && value->value->special != ConstValSpecialRuntime && !non_null_comptime)
16179 return nullptr;16200 return nullptr;
16180 ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc);16201 ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc);
16181 ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child);16202 ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child);
...@@ -16204,6 +16225,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe...@@ -16204,6 +16225,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
16204 {16225 {
16205 return parent_result_loc;16226 return parent_result_loc;
16206 }16227 }
16228
16207 ZigType *parent_ptr_type = parent_result_loc->value->type;16229 ZigType *parent_ptr_type = parent_result_loc->value->type;
16208 assert(parent_ptr_type->id == ZigTypeIdPointer);16230 assert(parent_ptr_type->id == ZigTypeIdPointer);
16209 if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type,16231 if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type,
...@@ -16354,7 +16376,7 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s...@@ -16354,7 +16376,7 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s
16354 {16376 {
16355 result_loc_pass1->written = false;16377 result_loc_pass1->written = false;
16356 return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true);16378 return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true);
16357 } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion) {16379 } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion && value == nullptr) {
16358 if (value_type->id == ZigTypeIdErrorSet) {16380 if (value_type->id == ZigTypeIdErrorSet) {
16359 return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, true);16381 return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, true);
16360 } else {16382 } else {
...@@ -28238,3 +28260,11 @@ void IrInstruction::dump() {...@@ -28238,3 +28260,11 @@ void IrInstruction::dump() {
28238 ir_print_instruction(inst->scope->codegen, stderr, inst->child, 0, IrPassGen);28260 ir_print_instruction(inst->scope->codegen, stderr, inst->child, 0, IrPassGen);
28239 }28261 }
28240}28262}
28263
28264void IrAnalyze::dump() {
28265 ir_print(this->codegen, stderr, this->new_irb.exec, 0, IrPassGen);
28266 if (this->new_irb.current_basic_block != nullptr) {
28267 fprintf(stderr, "Current basic block:\n");
28268 ir_print_basic_block(this->codegen, stderr, this->new_irb.current_basic_block, 1, IrPassGen);
28269 }
28270}
src/ir_print.cpp+32-12
...@@ -2530,6 +2530,37 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction, bool...@@ -2530,6 +2530,37 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction, bool
2530 fprintf(irp->f, "\n");2530 fprintf(irp->f, "\n");
2531}2531}
25322532
2533static void irp_print_basic_block(IrPrint *irp, IrBasicBlock *current_block) {
2534 fprintf(irp->f, "%s_%" ZIG_PRI_usize ":\n", current_block->name_hint, current_block->debug_id);
2535 for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) {
2536 IrInstruction *instruction = current_block->instruction_list.at(instr_i);
2537 if (irp->pass != IrPassSrc) {
2538 irp->printed.put(instruction, 0);
2539 irp->pending.clear();
2540 }
2541 ir_print_instruction(irp, instruction, false);
2542 for (size_t j = 0; j < irp->pending.length; ++j)
2543 ir_print_instruction(irp, irp->pending.at(j), true);
2544 }
2545}
2546
2547void ir_print_basic_block(CodeGen *codegen, FILE *f, IrBasicBlock *bb, int indent_size, IrPass pass) {
2548 IrPrint ir_print = {};
2549 ir_print.pass = pass;
2550 ir_print.codegen = codegen;
2551 ir_print.f = f;
2552 ir_print.indent = indent_size;
2553 ir_print.indent_size = indent_size;
2554 ir_print.printed = {};
2555 ir_print.printed.init(64);
2556 ir_print.pending = {};
2557
2558 irp_print_basic_block(&ir_print, bb);
2559
2560 ir_print.pending.deinit();
2561 ir_print.printed.deinit();
2562}
2563
2533void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_size, IrPass pass) {2564void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_size, IrPass pass) {
2534 IrPrint ir_print = {};2565 IrPrint ir_print = {};
2535 IrPrint *irp = &ir_print;2566 IrPrint *irp = &ir_print;
...@@ -2543,18 +2574,7 @@ void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_si...@@ -2543,18 +2574,7 @@ void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_si
2543 irp->pending = {};2574 irp->pending = {};
25442575
2545 for (size_t bb_i = 0; bb_i < executable->basic_block_list.length; bb_i += 1) {2576 for (size_t bb_i = 0; bb_i < executable->basic_block_list.length; bb_i += 1) {
2546 IrBasicBlock *current_block = executable->basic_block_list.at(bb_i);2577 irp_print_basic_block(irp, executable->basic_block_list.at(bb_i));
2547 fprintf(irp->f, "%s_%" ZIG_PRI_usize ":\n", current_block->name_hint, current_block->debug_id);
2548 for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) {
2549 IrInstruction *instruction = current_block->instruction_list.at(instr_i);
2550 if (irp->pass != IrPassSrc) {
2551 irp->printed.put(instruction, 0);
2552 irp->pending.clear();
2553 }
2554 ir_print_instruction(irp, instruction, false);
2555 for (size_t j = 0; j < irp->pending.length; ++j)
2556 ir_print_instruction(irp, irp->pending.at(j), true);
2557 }
2558 }2578 }
25592579
2560 irp->pending.deinit();2580 irp->pending.deinit();
src/ir_print.hpp+1
...@@ -15,6 +15,7 @@...@@ -15,6 +15,7 @@
15void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_size, IrPass pass);15void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_size, IrPass pass);
16void ir_print_instruction(CodeGen *codegen, FILE *f, IrInstruction *instruction, int indent_size, IrPass pass);16void ir_print_instruction(CodeGen *codegen, FILE *f, IrInstruction *instruction, int indent_size, IrPass pass);
17void ir_print_const_expr(CodeGen *codegen, FILE *f, ZigValue *value, int indent_size, IrPass pass);17void ir_print_const_expr(CodeGen *codegen, FILE *f, ZigValue *value, int indent_size, IrPass pass);
18void ir_print_basic_block(CodeGen *codegen, FILE *f, IrBasicBlock *bb, int indent_size, IrPass pass);
1819
19const char* ir_instruction_type_str(IrInstructionId id);20const char* ir_instruction_type_str(IrInstructionId id);
2021
test/stage1/behavior/cast.zig+13
...@@ -697,3 +697,16 @@ test "cast i8 fn call peers to i32 result" {...@@ -697,3 +697,16 @@ test "cast i8 fn call peers to i32 result" {
697 S.doTheTest();697 S.doTheTest();
698 comptime S.doTheTest();698 comptime S.doTheTest();
699}699}
700
701test "return u8 coercing into ?u32 return type" {
702 const S = struct {
703 fn doTheTest() void {
704 expect(foo(123).? == 123);
705 }
706 fn foo(arg: u8) ?u32 {
707 return arg;
708 }
709 };
710 S.doTheTest();
711 comptime S.doTheTest();
712}
test/stage1/behavior/union.zig+29
...@@ -582,3 +582,32 @@ test "update the tag value for zero-sized unions" {...@@ -582,3 +582,32 @@ test "update the tag value for zero-sized unions" {
582 x = S{ .U1 = {} };582 x = S{ .U1 = {} };
583 expect(x == .U1);583 expect(x == .U1);
584}584}
585
586test "function call result coerces from tagged union to the tag" {
587 const S = struct {
588 const Arch = union(enum) {
589 One,
590 Two: usize,
591 };
592
593 const ArchTag = @TagType(Arch);
594
595 fn doTheTest() void {
596 var x: ArchTag = getArch1();
597 expect(x == .One);
598
599 var y: ArchTag = getArch2();
600 expect(y == .Two);
601 }
602
603 pub fn getArch1() Arch {
604 return .One;
605 }
606
607 pub fn getArch2() Arch {
608 return .{ .Two = 99 };
609 }
610 };
611 S.doTheTest();
612 comptime S.doTheTest();
613}