| author | |
| committer | |
| log | 41bf81dc3231eb763c93eb95b152e7ab8d3c5af8 |
| tree | 6610d43dfab44f104e7894f3d31991ff38821512 |
| parent | 1bdc2b777bc247c52942189666bc484d8e740b16 |
This reverts commit 135b91aecd9be1f6f5806b667e07e383dd481198.
"endsWithBreak()" is not a meaningful question to ask and should not be
used this way. A simple example that defeats this logic is:
```zig
export fn entry() void {
outer: {
{
break :outer;
}
return;
}
}
```3 files changed, 0 insertions(+), 37 deletions(-)
src/AstGen.zig-10| ... | ... | @@ -1967,9 +1967,6 @@ fn blockExpr( |
| 1967 | 1967 | } |
| 1968 | 1968 | |
| 1969 | 1969 | try blockExprStmts(gz, scope, statements); |
| 1970 | if (gz.endsWithNoReturn() and !gz.endsWithBreak()) { | |
| 1971 | return Zir.Inst.Ref.unreachable_value; | |
| 1972 | } | |
| 1973 | 1970 | return rvalue(gz, rl, .void_value, block_node); |
| 1974 | 1971 | } |
| 1975 | 1972 | |
| ... | ... | @@ -9933,13 +9930,6 @@ const GenZir = struct { |
| 9933 | 9930 | return tags[last_inst].isNoReturn(); |
| 9934 | 9931 | } |
| 9935 | 9932 | |
| 9936 | fn endsWithBreak(gz: GenZir) bool { | |
| 9937 | if (gz.isEmpty()) return false; | |
| 9938 | const tags = gz.astgen.instructions.items(.tag); | |
| 9939 | const last_inst = gz.instructions.items[gz.instructions.items.len - 1]; | |
| 9940 | return tags[last_inst].isBreak(); | |
| 9941 | } | |
| 9942 | ||
| 9943 | 9933 | /// TODO all uses of this should be replaced with uses of `endsWithNoReturn`. |
| 9944 | 9934 | fn refIsNoReturn(gz: GenZir, inst_ref: Zir.Inst.Ref) bool { |
| 9945 | 9935 | if (inst_ref == .unreachable_value) return true; |
src/Zir.zig-13| ... | ... | @@ -1250,19 +1250,6 @@ pub const Inst = struct { |
| 1250 | 1250 | }; |
| 1251 | 1251 | } |
| 1252 | 1252 | |
| 1253 | /// Returns whether the instruction is a "break". This differs from | |
| 1254 | /// isNoReturn because a "break" in a block statement is not a | |
| 1255 | /// "noreturn" for the outer scope, whereas the other "noreturn" | |
| 1256 | /// instructions are. | |
| 1257 | pub fn isBreak(tag: Tag) bool { | |
| 1258 | return switch (tag) { | |
| 1259 | .@"break", | |
| 1260 | .break_inline, | |
| 1261 | => true, | |
| 1262 | else => false, | |
| 1263 | }; | |
| 1264 | } | |
| 1265 | ||
| 1266 | 1253 | /// AstGen uses this to find out if `Ref.void_value` should be used in place |
| 1267 | 1254 | /// of the result of a given instruction. This allows Sema to forego adding |
| 1268 | 1255 | /// the instruction to the map after analysis. |
test/cases/compile_errors/stage2/code_after_return_in_block_is_unreachable.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | export fn entry() void { | |
| 2 | { | |
| 3 | return; | |
| 4 | } | |
| 5 | ||
| 6 | return; | |
| 7 | } | |
| 8 | ||
| 9 | // error | |
| 10 | // target=native | |
| 11 | // | |
| 12 | // :6:5: error: unreachable code | |
| 13 | // :2:5: note: control flow is diverted here | |
| 14 |