| author | |
| committer | |
| log | 83673a8b5f508376c81deaa4b01815474873eb69 |
| tree | ccfd27379ec2bb5af7e57ce188350f3831856e04 |
| parent | fd6b79e67f0cf91a72c121fc6fd484a03f487506 |
This was broken by 58caed1c71179f48c4e7bffadef0392fa8381e72
Closes #140535 files changed, 33 insertions(+), 2 deletions(-)
src/AstGen.zig+2-1| ... | ... | @@ -2463,6 +2463,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As |
| 2463 | 2463 | .is_non_null_ptr, |
| 2464 | 2464 | .is_non_err, |
| 2465 | 2465 | .is_non_err_ptr, |
| 2466 | .ret_is_non_err, | |
| 2466 | 2467 | .mod_rem, |
| 2467 | 2468 | .mul, |
| 2468 | 2469 | .mulwrap, |
| ... | ... | @@ -7012,7 +7013,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref |
| 7012 | 7013 | |
| 7013 | 7014 | // Emit conditional branch for generating errdefers. |
| 7014 | 7015 | const result = if (ri.rl == .ptr) try gz.addUnNode(.load, ri.rl.ptr.inst, node) else operand; |
| 7015 | const is_non_err = try gz.addUnNode(.is_non_err, result, node); | |
| 7016 | const is_non_err = try gz.addUnNode(.ret_is_non_err, result, node); | |
| 7016 | 7017 | const condbr = try gz.addCondBr(.condbr, node); |
| 7017 | 7018 | |
| 7018 | 7019 | var then_scope = gz.makeSubBlock(scope); |
src/Sema.zig+13-1| ... | ... | @@ -953,6 +953,7 @@ fn analyzeBodyInner( |
| 953 | 953 | .int_type => try sema.zirIntType(block, inst), |
| 954 | 954 | .is_non_err => try sema.zirIsNonErr(block, inst), |
| 955 | 955 | .is_non_err_ptr => try sema.zirIsNonErrPtr(block, inst), |
| 956 | .ret_is_non_err => try sema.zirRetIsNonErr(block, inst), | |
| 956 | 957 | .is_non_null => try sema.zirIsNonNull(block, inst), |
| 957 | 958 | .is_non_null_ptr => try sema.zirIsNonNullPtr(block, inst), |
| 958 | 959 | .merge_error_sets => try sema.zirMergeErrorSets(block, inst), |
| ... | ... | @@ -10288,6 +10289,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10288 | 10289 | .ret_err_value_code, |
| 10289 | 10290 | .restore_err_ret_index, |
| 10290 | 10291 | .is_non_err, |
| 10292 | .ret_is_non_err, | |
| 10291 | 10293 | .condbr, |
| 10292 | 10294 | => {}, |
| 10293 | 10295 | else => break, |
| ... | ... | @@ -16577,7 +16579,7 @@ fn zirIsNonErr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16577 | 16579 | const src = inst_data.src(); |
| 16578 | 16580 | const operand = try sema.resolveInst(inst_data.operand); |
| 16579 | 16581 | try sema.checkErrorType(block, src, sema.typeOf(operand)); |
| 16580 | return sema.analyzeIsNonErr(block, inst_data.src(), operand); | |
| 16582 | return sema.analyzeIsNonErr(block, src, operand); | |
| 16581 | 16583 | } |
| 16582 | 16584 | |
| 16583 | 16585 | fn zirIsNonErrPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -16592,6 +16594,16 @@ fn zirIsNonErrPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 16592 | 16594 | return sema.analyzeIsNonErr(block, src, loaded); |
| 16593 | 16595 | } |
| 16594 | 16596 | |
| 16597 | fn zirRetIsNonErr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | |
| 16598 | const tracy = trace(@src()); | |
| 16599 | defer tracy.end(); | |
| 16600 | ||
| 16601 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; | |
| 16602 | const src = inst_data.src(); | |
| 16603 | const operand = try sema.resolveInst(inst_data.operand); | |
| 16604 | return sema.analyzeIsNonErr(block, src, operand); | |
| 16605 | } | |
| 16606 | ||
| 16595 | 16607 | fn zirCondbr( |
| 16596 | 16608 | sema: *Sema, |
| 16597 | 16609 | parent_block: *Block, |
src/Zir.zig+6| ... | ... | @@ -481,6 +481,9 @@ pub const Inst = struct { |
| 481 | 481 | /// Return a boolean false if dereferenced pointer is an error |
| 482 | 482 | /// Uses the `un_node` field. |
| 483 | 483 | is_non_err_ptr, |
| 484 | /// Same as `is_non_er` but doesn't validate that the type can be an error. | |
| 485 | /// Uses the `un_node` field. | |
| 486 | ret_is_non_err, | |
| 484 | 487 | /// A labeled block of code that loops forever. At the end of the body will have either |
| 485 | 488 | /// a `repeat` instruction or a `repeat_inline` instruction. |
| 486 | 489 | /// Uses the `pl_node` field. The AST node is either a for loop or while loop. |
| ... | ... | @@ -1083,6 +1086,7 @@ pub const Inst = struct { |
| 1083 | 1086 | .is_non_null_ptr, |
| 1084 | 1087 | .is_non_err, |
| 1085 | 1088 | .is_non_err_ptr, |
| 1089 | .ret_is_non_err, | |
| 1086 | 1090 | .mod_rem, |
| 1087 | 1091 | .mul, |
| 1088 | 1092 | .mulwrap, |
| ... | ... | @@ -1386,6 +1390,7 @@ pub const Inst = struct { |
| 1386 | 1390 | .is_non_null_ptr, |
| 1387 | 1391 | .is_non_err, |
| 1388 | 1392 | .is_non_err_ptr, |
| 1393 | .ret_is_non_err, | |
| 1389 | 1394 | .mod_rem, |
| 1390 | 1395 | .mul, |
| 1391 | 1396 | .mulwrap, |
| ... | ... | @@ -1640,6 +1645,7 @@ pub const Inst = struct { |
| 1640 | 1645 | .is_non_null_ptr = .un_node, |
| 1641 | 1646 | .is_non_err = .un_node, |
| 1642 | 1647 | .is_non_err_ptr = .un_node, |
| 1648 | .ret_is_non_err = .un_node, | |
| 1643 | 1649 | .loop = .pl_node, |
| 1644 | 1650 | .repeat = .node, |
| 1645 | 1651 | .repeat_inline = .node, |
src/print_zir.zig+1| ... | ... | @@ -179,6 +179,7 @@ const Writer = struct { |
| 179 | 179 | .is_non_null_ptr, |
| 180 | 180 | .is_non_err, |
| 181 | 181 | .is_non_err_ptr, |
| 182 | .ret_is_non_err, | |
| 182 | 183 | .typeof, |
| 183 | 184 | .struct_init_empty, |
| 184 | 185 | .type_info, |
test/behavior/defer.zig+11| ... | ... | @@ -148,3 +148,14 @@ test "simple else prong doesn't emit an error for unreachable else prong" { |
| 148 | 148 | }; |
| 149 | 149 | try expect(a == 1); |
| 150 | 150 | } |
| 151 | ||
| 152 | test "errdefer used in function that doesn't return an error" { | |
| 153 | const S = struct { | |
| 154 | fn foo() u8 { | |
| 155 | var a: u8 = 5; | |
| 156 | errdefer a += 1; | |
| 157 | return a; | |
| 158 | } | |
| 159 | }; | |
| 160 | try expect(S.foo() == 5); | |
| 161 | } |