| author | |
| committer | |
| log | 36faf76fe1eeb3aafcc4de94fc83fd8ca3b18b25 |
| tree | 2d733976d1e99f1add9d20bd4a2c2619effc550b |
| parent | d4cac43d308ffa930cd7174567be7c1fe18e29fb |
Fixes #309122 files changed, 142 insertions(+), 0 deletions(-)
lib/std/zig/AstGen.zig+16| ... | @@ -6656,9 +6656,16 @@ fn whileExpr( | ... | @@ -6656,9 +6656,16 @@ fn whileExpr( |
| 6656 | .operand = undefined, | 6656 | .operand = undefined, |
| 6657 | } }, | 6657 | } }, |
| 6658 | }); | 6658 | }); |
| 6659 | if (!continue_scope.is_comptime) { | ||
| 6660 | _ = try continue_scope.addRestoreErrRetIndex(.{ .block = continue_block }, .always, then_node); | ||
| 6661 | } | ||
| 6659 | _ = try continue_scope.addBreak(break_tag, continue_block, .void_value); | 6662 | _ = try continue_scope.addBreak(break_tag, continue_block, .void_value); |
| 6660 | } | 6663 | } |
| 6661 | try continue_scope.setBlockBody(continue_block); | 6664 | try continue_scope.setBlockBody(continue_block); |
| 6665 | if (!then_scope.is_comptime) { | ||
| 6666 | const cont_node = while_full.ast.cont_expr.unwrap() orelse then_node; | ||
| 6667 | _ = try then_scope.addRestoreErrRetIndex(.{ .block = cond_block }, .always, cont_node); | ||
| 6668 | } | ||
| 6662 | _ = try then_scope.addBreak(break_tag, cond_block, .void_value); | 6669 | _ = try then_scope.addBreak(break_tag, cond_block, .void_value); |
| 6663 | 6670 | ||
| 6664 | var else_scope = parent_gz.makeSubBlock(&cond_scope.base); | 6671 | var else_scope = parent_gz.makeSubBlock(&cond_scope.base); |
| ... | @@ -6703,6 +6710,9 @@ fn whileExpr( | ... | @@ -6703,6 +6710,9 @@ fn whileExpr( |
| 6703 | 6710 | ||
| 6704 | try checkUsed(parent_gz, &else_scope.base, sub_scope); | 6711 | try checkUsed(parent_gz, &else_scope.base, sub_scope); |
| 6705 | if (!else_scope.endsWithNoReturn()) { | 6712 | if (!else_scope.endsWithNoReturn()) { |
| 6713 | if (!else_scope.is_comptime) { | ||
| 6714 | _ = try else_scope.addRestoreErrRetIndex(.{ .block = loop_block }, .always, else_node); | ||
| 6715 | } | ||
| 6706 | _ = try else_scope.addBreakWithSrcNode(break_tag, loop_block, else_result, else_node); | 6716 | _ = try else_scope.addBreakWithSrcNode(break_tag, loop_block, else_result, else_node); |
| 6707 | } | 6717 | } |
| 6708 | } else { | 6718 | } else { |
| ... | @@ -6973,6 +6983,9 @@ fn forExpr( | ... | @@ -6973,6 +6983,9 @@ fn forExpr( |
| 6973 | }); | 6983 | }); |
| 6974 | 6984 | ||
| 6975 | const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break"; | 6985 | const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break"; |
| 6986 | if (!then_scope.is_comptime) { | ||
| 6987 | _ = try then_scope.addRestoreErrRetIndex(.{ .block = cond_block }, .always, then_node); | ||
| 6988 | } | ||
| 6976 | _ = try then_scope.addBreak(break_tag, cond_block, .void_value); | 6989 | _ = try then_scope.addBreak(break_tag, cond_block, .void_value); |
| 6977 | 6990 | ||
| 6978 | var else_scope = parent_gz.makeSubBlock(&cond_scope.base); | 6991 | var else_scope = parent_gz.makeSubBlock(&cond_scope.base); |
| ... | @@ -6990,6 +7003,9 @@ fn forExpr( | ... | @@ -6990,6 +7003,9 @@ fn forExpr( |
| 6990 | _ = try addEnsureResult(&else_scope, else_result, else_node); | 7003 | _ = try addEnsureResult(&else_scope, else_result, else_node); |
| 6991 | } | 7004 | } |
| 6992 | if (!else_scope.endsWithNoReturn()) { | 7005 | if (!else_scope.endsWithNoReturn()) { |
| 7006 | if (!else_scope.is_comptime) { | ||
| 7007 | _ = try else_scope.addRestoreErrRetIndex(.{ .block = loop_block }, .always, else_node); | ||
| 7008 | } | ||
| 6993 | _ = try else_scope.addBreakWithSrcNode(break_tag, loop_block, else_result, else_node); | 7009 | _ = try else_scope.addBreakWithSrcNode(break_tag, loop_block, else_result, else_node); |
| 6994 | } | 7010 | } |
| 6995 | } else { | 7011 | } else { |
test/error_traces.zig+126| ... | @@ -92,6 +92,132 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. | ... | @@ -92,6 +92,132 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 92 | , | 92 | , |
| 93 | }); | 93 | }); |
| 94 | 94 | ||
| 95 | cases.addCase(.{ | ||
| 96 | .name = "for loop pops error return trace", | ||
| 97 | .source = | ||
| 98 | \\fn foo() !void { return error.FooError; } | ||
| 99 | \\ | ||
| 100 | \\pub fn main() !void { | ||
| 101 | \\ for (0..2) |_| { | ||
| 102 | \\ const f = foo(); | ||
| 103 | \\ f catch {}; | ||
| 104 | \\ } else { | ||
| 105 | \\ const f = foo(); | ||
| 106 | \\ f catch {}; | ||
| 107 | \\ } | ||
| 108 | \\ return error.Stop; | ||
| 109 | \\} | ||
| 110 | , | ||
| 111 | .expect_error = "Stop", | ||
| 112 | .expect_trace = | ||
| 113 | \\source.zig:11:5: [address] in main | ||
| 114 | \\ return error.Stop; | ||
| 115 | \\ ^ | ||
| 116 | , | ||
| 117 | .disable_trace_optimized = &.{ | ||
| 118 | .{ .x86_64, .windows }, | ||
| 119 | .{ .x86, .windows }, | ||
| 120 | .{ .x86_64, .macos }, | ||
| 121 | .{ .aarch64, .macos }, | ||
| 122 | }, | ||
| 123 | }); | ||
| 124 | |||
| 125 | cases.addCase(.{ | ||
| 126 | .name = "implicit continue in for loop pops stale error return trace", | ||
| 127 | .source = | ||
| 128 | \\fn foo() !void { return error.FooError; } | ||
| 129 | \\ | ||
| 130 | \\pub fn main() !void { | ||
| 131 | \\ for (0..2) |i| { | ||
| 132 | \\ const f = foo(); | ||
| 133 | \\ f catch {}; | ||
| 134 | \\ | ||
| 135 | \\ if (i == 1) return error.Stop; | ||
| 136 | \\ } | ||
| 137 | \\} | ||
| 138 | , | ||
| 139 | .expect_error = "Stop", | ||
| 140 | .expect_trace = | ||
| 141 | \\source.zig:1:18: [address] in foo | ||
| 142 | \\fn foo() !void { return error.FooError; } | ||
| 143 | \\ ^ | ||
| 144 | \\source.zig:8:21: [address] in main | ||
| 145 | \\ if (i == 1) return error.Stop; | ||
| 146 | \\ ^ | ||
| 147 | , | ||
| 148 | .disable_trace_optimized = &.{ | ||
| 149 | .{ .x86_64, .windows }, | ||
| 150 | .{ .x86, .windows }, | ||
| 151 | .{ .x86_64, .macos }, | ||
| 152 | .{ .aarch64, .macos }, | ||
| 153 | }, | ||
| 154 | }); | ||
| 155 | |||
| 156 | cases.addCase(.{ | ||
| 157 | .name = "while loop pops error return trace", | ||
| 158 | .source = | ||
| 159 | \\fn foo() !void { return error.FooError; } | ||
| 160 | \\ | ||
| 161 | \\pub fn main() !void { | ||
| 162 | \\ var i: usize = 0; | ||
| 163 | \\ while (i < 2) { | ||
| 164 | \\ const f = foo(); | ||
| 165 | \\ f catch {}; | ||
| 166 | \\ i += 1; | ||
| 167 | \\ } else { | ||
| 168 | \\ const f = foo(); | ||
| 169 | \\ f catch {}; | ||
| 170 | \\ } | ||
| 171 | \\ return error.Stop; | ||
| 172 | \\} | ||
| 173 | , | ||
| 174 | .expect_error = "Stop", | ||
| 175 | .expect_trace = | ||
| 176 | \\source.zig:13:5: [address] in main | ||
| 177 | \\ return error.Stop; | ||
| 178 | \\ ^ | ||
| 179 | , | ||
| 180 | .disable_trace_optimized = &.{ | ||
| 181 | .{ .x86_64, .windows }, | ||
| 182 | .{ .x86, .windows }, | ||
| 183 | .{ .x86_64, .macos }, | ||
| 184 | .{ .aarch64, .macos }, | ||
| 185 | }, | ||
| 186 | }); | ||
| 187 | |||
| 188 | cases.addCase(.{ | ||
| 189 | .name = "implicit continue in while loop pops stale error return trace", | ||
| 190 | .source = | ||
| 191 | \\fn foo() !void { return error.FooError; } | ||
| 192 | \\ | ||
| 193 | \\pub fn main() !void { | ||
| 194 | \\ var i: usize = 0; | ||
| 195 | \\ while (i < 2) { | ||
| 196 | \\ const f = foo(); | ||
| 197 | \\ f catch {}; | ||
| 198 | \\ | ||
| 199 | \\ if (i == 1) return error.Stop; | ||
| 200 | \\ i += 1; | ||
| 201 | \\ } | ||
| 202 | \\} | ||
| 203 | , | ||
| 204 | .expect_error = "Stop", | ||
| 205 | .expect_trace = | ||
| 206 | \\source.zig:1:18: [address] in foo | ||
| 207 | \\fn foo() !void { return error.FooError; } | ||
| 208 | \\ ^ | ||
| 209 | \\source.zig:9:21: [address] in main | ||
| 210 | \\ if (i == 1) return error.Stop; | ||
| 211 | \\ ^ | ||
| 212 | , | ||
| 213 | .disable_trace_optimized = &.{ | ||
| 214 | .{ .x86_64, .windows }, | ||
| 215 | .{ .x86, .windows }, | ||
| 216 | .{ .x86_64, .macos }, | ||
| 217 | .{ .aarch64, .macos }, | ||
| 218 | }, | ||
| 219 | }); | ||
| 220 | |||
| 95 | cases.addCase(.{ | 221 | cases.addCase(.{ |
| 96 | .name = "try return + handled catch/if-else", | 222 | .name = "try return + handled catch/if-else", |
| 97 | .source = | 223 | .source = |