| ... | ... | @@ -1156,16 +1156,6 @@ fn fnProtoExpr( |
| 1156 | 1156 | return astgen.failNode(fn_proto.ast.section_expr, "linksection not allowed on function prototypes", .{}); |
| 1157 | 1157 | } |
| 1158 | 1158 | |
| 1159 | | const maybe_bang = tree.firstToken(fn_proto.ast.return_type) - 1; |
| 1160 | | const is_inferred_error = token_tags[maybe_bang] == .bang; |
| 1161 | | if (is_inferred_error) { |
| 1162 | | return astgen.failTok(maybe_bang, "function prototype may not have inferred error set", .{}); |
| 1163 | | } |
| 1164 | | var ret_gz = gz.makeSubBlock(scope); |
| 1165 | | defer ret_gz.instructions.deinit(gpa); |
| 1166 | | const ret_ty = try expr(&ret_gz, scope, coerced_type_rl, fn_proto.ast.return_type); |
| 1167 | | const ret_br = try ret_gz.addBreak(.break_inline, 0, ret_ty); |
| 1168 | | |
| 1169 | 1159 | const cc: Zir.Inst.Ref = if (fn_proto.ast.callconv_expr != 0) |
| 1170 | 1160 | try expr( |
| 1171 | 1161 | gz, |
| ... | ... | @@ -1176,6 +1166,16 @@ fn fnProtoExpr( |
| 1176 | 1166 | else |
| 1177 | 1167 | Zir.Inst.Ref.none; |
| 1178 | 1168 | |
| 1169 | const maybe_bang = tree.firstToken(fn_proto.ast.return_type) - 1; |
| 1170 | const is_inferred_error = token_tags[maybe_bang] == .bang; |
| 1171 | if (is_inferred_error) { |
| 1172 | return astgen.failTok(maybe_bang, "function prototype may not have inferred error set", .{}); |
| 1173 | } |
| 1174 | var ret_gz = gz.makeSubBlock(scope); |
| 1175 | defer ret_gz.instructions.deinit(gpa); |
| 1176 | const ret_ty = try expr(&ret_gz, scope, coerced_type_rl, fn_proto.ast.return_type); |
| 1177 | const ret_br = try ret_gz.addBreak(.break_inline, 0, ret_ty); |
| 1178 | |
| 1179 | 1179 | const result = try gz.addFunc(.{ |
| 1180 | 1180 | .src_node = fn_proto.ast.proto_node, |
| 1181 | 1181 | .param_block = 0, |
| ... | ... | @@ -3182,11 +3182,6 @@ fn fnDecl( |
| 3182 | 3182 | break :inst try comptimeExpr(&decl_gz, params_scope, .{ .ty = .const_slice_u8_type }, fn_proto.ast.section_expr); |
| 3183 | 3183 | }; |
| 3184 | 3184 | |
| 3185 | | var ret_gz = decl_gz.makeSubBlock(params_scope); |
| 3186 | | defer ret_gz.instructions.deinit(gpa); |
| 3187 | | const ret_ty = try expr(&ret_gz, params_scope, coerced_type_rl, fn_proto.ast.return_type); |
| 3188 | | const ret_br = try ret_gz.addBreak(.break_inline, 0, ret_ty); |
| 3189 | | |
| 3190 | 3185 | const cc: Zir.Inst.Ref = blk: { |
| 3191 | 3186 | if (fn_proto.ast.callconv_expr != 0) { |
| 3192 | 3187 | if (has_inline_keyword) { |
| ... | ... | @@ -3212,6 +3207,11 @@ fn fnDecl( |
| 3212 | 3207 | } |
| 3213 | 3208 | }; |
| 3214 | 3209 | |
| 3210 | var ret_gz = decl_gz.makeSubBlock(params_scope); |
| 3211 | defer ret_gz.instructions.deinit(gpa); |
| 3212 | const ret_ty = try expr(&ret_gz, params_scope, coerced_type_rl, fn_proto.ast.return_type); |
| 3213 | const ret_br = try ret_gz.addBreak(.break_inline, 0, ret_ty); |
| 3214 | |
| 3215 | 3215 | const func_inst: Zir.Inst.Ref = if (body_node == 0) func: { |
| 3216 | 3216 | if (!is_extern) { |
| 3217 | 3217 | return astgen.failTok(fn_proto.ast.fn_token, "non-extern function has no body", .{}); |
| ... | ... | @@ -6500,7 +6500,8 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref |
| 6500 | 6500 | }, |
| 6501 | 6501 | .always => { |
| 6502 | 6502 | // Value is always an error. Emit both error defers and regular defers. |
| 6503 | | const err_code = try gz.addUnNode(.err_union_code, operand, node); |
| 6503 | const result = if (rl == .ptr) try gz.addUnNode(.load, rl.ptr, node) else operand; |
| 6504 | const err_code = try gz.addUnNode(.err_union_code, result, node); |
| 6504 | 6505 | try genDefers(gz, defer_outer, scope, .{ .both = err_code }); |
| 6505 | 6506 | try gz.addRet(rl, operand, node); |
| 6506 | 6507 | return Zir.Inst.Ref.unreachable_value; |
| ... | ... | @@ -6515,7 +6516,8 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref |
| 6515 | 6516 | } |
| 6516 | 6517 | |
| 6517 | 6518 | // Emit conditional branch for generating errdefers. |
| 6518 | | const is_non_err = try gz.addUnNode(.is_non_err, operand, node); |
| 6519 | const result = if (rl == .ptr) try gz.addUnNode(.load, rl.ptr, node) else operand; |
| 6520 | const is_non_err = try gz.addUnNode(.is_non_err, result, node); |
| 6519 | 6521 | const condbr = try gz.addCondBr(.condbr, node); |
| 6520 | 6522 | |
| 6521 | 6523 | var then_scope = gz.makeSubBlock(scope); |
| ... | ... | @@ -6528,7 +6530,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref |
| 6528 | 6530 | defer else_scope.instructions.deinit(astgen.gpa); |
| 6529 | 6531 | |
| 6530 | 6532 | const which_ones: DefersToEmit = if (!defer_counts.need_err_code) .both_sans_err else .{ |
| 6531 | | .both = try else_scope.addUnNode(.err_union_code, operand, node), |
| 6533 | .both = try else_scope.addUnNode(.err_union_code, result, node), |
| 6532 | 6534 | }; |
| 6533 | 6535 | try genDefers(&else_scope, defer_outer, scope, which_ones); |
| 6534 | 6536 | try else_scope.addRet(rl, operand, node); |
| ... | ... | @@ -8514,10 +8516,10 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) enum { never |
| 8514 | 8516 | .unwrap_optional, |
| 8515 | 8517 | => node = node_datas[node].lhs, |
| 8516 | 8518 | |
| 8517 | | // Forward the question to the RHS sub-expression. |
| 8519 | // LHS sub-expression may still be an error under the outer optional or error union |
| 8518 | 8520 | .@"catch", |
| 8519 | 8521 | .@"orelse", |
| 8520 | | => node = node_datas[node].rhs, |
| 8522 | => return .maybe, |
| 8521 | 8523 | |
| 8522 | 8524 | .block_two, |
| 8523 | 8525 | .block_two_semicolon, |
| ... | ... | @@ -8544,11 +8546,18 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) enum { never |
| 8544 | 8546 | // If the builtin is an invalid name, we don't cause an error here; instead |
| 8545 | 8547 | // let it pass, and the error will be "invalid builtin function" later. |
| 8546 | 8548 | const builtin_info = BuiltinFn.list.get(builtin_name) orelse return .maybe; |
| 8547 | | if (builtin_info.tag == .err_set_cast) { |
| 8548 | | return .always; |
| 8549 | | } else { |
| 8550 | | return .never; |
| 8551 | | } |
| 8549 | return switch (builtin_info.tag) { |
| 8550 | .as, |
| 8551 | .call, |
| 8552 | .field, |
| 8553 | => .maybe, |
| 8554 | |
| 8555 | .err_set_cast, |
| 8556 | .int_to_error, |
| 8557 | => .always, |
| 8558 | |
| 8559 | else => .never, |
| 8560 | }; |
| 8552 | 8561 | }, |
| 8553 | 8562 | } |
| 8554 | 8563 | } |