| ... | ... | @@ -822,7 +822,7 @@ pub fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inn |
| 822 | 822 | .@"await" => return astgen.failNode(node, "async and related features are not yet supported", .{}), |
| 823 | 823 | .@"resume" => return astgen.failNode(node, "async and related features are not yet supported", .{}), |
| 824 | 824 | |
| 825 | | .@"try" => return tryExpr(gz, scope, rl, node_datas[node].lhs), |
| 825 | .@"try" => return tryExpr(gz, scope, rl, node, node_datas[node].lhs), |
| 826 | 826 | |
| 827 | 827 | .array_init_one, .array_init_one_comma => { |
| 828 | 828 | var elements: [1]ast.Node.Index = undefined; |
| ... | ... | @@ -1247,8 +1247,13 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn |
| 1247 | 1247 | }, |
| 1248 | 1248 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, |
| 1249 | 1249 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, |
| 1250 | | .defer_normal => @panic("TODO break/defer"), |
| 1251 | | .defer_error => @panic("TODO break/defer"), |
| 1250 | .defer_normal => { |
| 1251 | const defer_scope = scope.cast(Scope.Defer).?; |
| 1252 | scope = defer_scope.parent; |
| 1253 | const expr_node = node_datas[defer_scope.defer_node].rhs; |
| 1254 | try unusedResultExpr(parent_gz, defer_scope.parent, expr_node); |
| 1255 | }, |
| 1256 | .defer_error => scope = scope.cast(Scope.Defer).?.parent, |
| 1252 | 1257 | else => if (break_label != 0) { |
| 1253 | 1258 | const label_name = try astgen.identifierTokenString(break_label); |
| 1254 | 1259 | return astgen.failTok(break_label, "label not found: '{s}'", .{label_name}); |
| ... | ... | @@ -1300,7 +1305,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) |
| 1300 | 1305 | const expr_node = node_datas[defer_scope.defer_node].rhs; |
| 1301 | 1306 | try unusedResultExpr(parent_gz, defer_scope.parent, expr_node); |
| 1302 | 1307 | }, |
| 1303 | | .defer_error => scope = scope.cast(Scope.LocalPtr).?.parent, |
| 1308 | .defer_error => scope = scope.cast(Scope.Defer).?.parent, |
| 1304 | 1309 | else => if (break_label != 0) { |
| 1305 | 1310 | const label_name = try astgen.identifierTokenString(break_label); |
| 1306 | 1311 | return astgen.failTok(break_label, "label not found: '{s}'", .{label_name}); |
| ... | ... | @@ -3291,10 +3296,15 @@ fn tryExpr( |
| 3291 | 3296 | scope: *Scope, |
| 3292 | 3297 | rl: ResultLoc, |
| 3293 | 3298 | node: ast.Node.Index, |
| 3299 | operand_node: ast.Node.Index, |
| 3294 | 3300 | ) InnerError!Zir.Inst.Ref { |
| 3295 | 3301 | const astgen = parent_gz.astgen; |
| 3296 | 3302 | const tree = &astgen.file.tree; |
| 3297 | 3303 | |
| 3304 | const fn_block = astgen.fn_block orelse { |
| 3305 | return astgen.failNode(node, "invalid 'try' outside function scope", .{}); |
| 3306 | }; |
| 3307 | |
| 3298 | 3308 | var block_scope: GenZir = .{ |
| 3299 | 3309 | .parent = scope, |
| 3300 | 3310 | .decl_node_index = parent_gz.decl_node_index, |
| ... | ... | @@ -3320,7 +3330,7 @@ fn tryExpr( |
| 3320 | 3330 | // We cannot use `block_scope.break_result_loc` because that has the bare |
| 3321 | 3331 | // type, whereas this expression has the optional type. Later we make |
| 3322 | 3332 | // up for this fact by calling rvalue on the else branch. |
| 3323 | | const operand = try expr(&block_scope, &block_scope.base, operand_rl, node); |
| 3333 | const operand = try expr(&block_scope, &block_scope.base, operand_rl, operand_node); |
| 3324 | 3334 | const cond = try block_scope.addUnNode(err_ops[0], operand, node); |
| 3325 | 3335 | const condbr = try block_scope.addCondBr(.condbr, node); |
| 3326 | 3336 | |
| ... | ... | @@ -3339,7 +3349,7 @@ fn tryExpr( |
| 3339 | 3349 | defer then_scope.instructions.deinit(astgen.gpa); |
| 3340 | 3350 | |
| 3341 | 3351 | const err_code = try then_scope.addUnNode(err_ops[1], operand, node); |
| 3342 | | try genDefers(&then_scope, &astgen.fn_block.?.base, scope, err_code); |
| 3352 | try genDefers(&then_scope, &fn_block.base, scope, err_code); |
| 3343 | 3353 | const then_result = try then_scope.addUnNode(.ret_node, err_code, node); |
| 3344 | 3354 | |
| 3345 | 3355 | var else_scope: GenZir = .{ |
| ... | ... | @@ -3406,7 +3416,7 @@ fn orelseCatchExpr( |
| 3406 | 3416 | block_scope.setBreakResultLoc(rl); |
| 3407 | 3417 | defer block_scope.instructions.deinit(astgen.gpa); |
| 3408 | 3418 | |
| 3409 | | // TODO handle catch |
| 3419 | // TODO get rid of optional_type_from_ptr_elem |
| 3410 | 3420 | const operand_rl: ResultLoc = switch (block_scope.break_result_loc) { |
| 3411 | 3421 | .ref => .ref, |
| 3412 | 3422 | .discard, .none, .none_or_ref, .block_ptr, .inferred_ptr => .none, |