diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2024-01-16 02:42:06 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-01-16 02:42:06 -0800 |
| commit | fe870418b1d83ad4e08a8fba9785289735d29f4f (patch) | |
| tree | b7fe04fb408e99e5799433447381e0f741ce5f54 /src | |
| parent | 7116b02210bcae7bafac9017a7e47a14b52eafc2 (diff) | |
| parent | 06410f58bd5378d5544f34dc3e87e3309cbdd332 (diff) | |
| download | zig-fe870418b1d83ad4e08a8fba9785289735d29f4f.tar.gz zig-fe870418b1d83ad4e08a8fba9785289735d29f4f.zip | |
Merge pull request #18584 from Techatrix/fix-switch-on-err
fix ast gen failure to catch incorrect by ref error captures
Diffstat (limited to 'src')
| -rw-r--r-- | src/AstGen.zig | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig index b32ee67b0a..6ef69e2c6b 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -841,13 +841,16 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE .@"if", => { const if_full = tree.fullIf(node).?; - if (if_full.error_token) |error_token| { - const tag = node_tags[if_full.ast.else_expr]; - if ((tag == .@"switch" or tag == .switch_comma) and - std.mem.eql(u8, tree.tokenSlice(error_token), tree.tokenSlice(error_token + 4))) - { - return switchExprErrUnion(gz, scope, ri.br(), node, .@"if"); + no_switch_on_err: { + const error_token = if_full.error_token orelse break :no_switch_on_err; + switch (node_tags[if_full.ast.else_expr]) { + .@"switch", .switch_comma => {}, + else => break :no_switch_on_err, } + const switch_operand = node_datas[if_full.ast.else_expr].lhs; + if (node_tags[switch_operand] != .identifier) break :no_switch_on_err; + if (!mem.eql(u8, tree.tokenSlice(error_token), tree.tokenSlice(main_tokens[switch_operand]))) break :no_switch_on_err; + return switchExprErrUnion(gz, scope, ri.br(), node, .@"if"); } return ifExpr(gz, scope, ri.br(), node, if_full); }, @@ -1026,16 +1029,21 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE }, .@"catch" => { const catch_token = main_tokens[node]; - const payload_token: ?Ast.TokenIndex = if (token_tags[catch_token + 1] == .pipe) blk: { - if (token_tags.len > catch_token + 6 and - token_tags[catch_token + 4] == .keyword_switch) - { - if (std.mem.eql(u8, tree.tokenSlice(catch_token + 2), tree.tokenSlice(catch_token + 6))) { - return switchExprErrUnion(gz, scope, ri.br(), node, .@"catch"); - } + const payload_token: ?Ast.TokenIndex = if (token_tags[catch_token + 1] == .pipe) + catch_token + 2 + else + null; + no_switch_on_err: { + const capture_token = payload_token orelse break :no_switch_on_err; + switch (node_tags[node_datas[node].rhs]) { + .@"switch", .switch_comma => {}, + else => break :no_switch_on_err, } - break :blk catch_token + 2; - } else null; + const switch_operand = node_datas[node_datas[node].rhs].lhs; + if (node_tags[switch_operand] != .identifier) break :no_switch_on_err; + if (!mem.eql(u8, tree.tokenSlice(capture_token), tree.tokenSlice(main_tokens[switch_operand]))) break :no_switch_on_err; + return switchExprErrUnion(gz, scope, ri.br(), node, .@"catch"); + } switch (ri.rl) { .ref, .ref_coerced_ty => return orelseCatchExpr( gz, @@ -7219,7 +7227,9 @@ fn switchExprErrUnion( }; const capture_token = case.payload_token orelse break :blk &err_scope.base; - assert(token_tags[capture_token] == .identifier); + if (token_tags[capture_token] != .identifier) { + return astgen.failTok(capture_token + 1, "error set cannot be captured by reference", .{}); + } const capture_slice = tree.tokenSlice(capture_token); if (mem.eql(u8, capture_slice, "_")) { |
