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