| ... | @@ -86,6 +86,7 @@ pub fn generate(gpa: *Allocator, tree: ast.Tree) InnerError!Zir { | ... | @@ -86,6 +86,7 @@ pub fn generate(gpa: *Allocator, tree: ast.Tree) InnerError!Zir { |
| 86 | | 86 | |
| 87 | var gen_scope: GenZir = .{ | 87 | var gen_scope: GenZir = .{ |
| 88 | .force_comptime = true, | 88 | .force_comptime = true, |
| | 89 | .in_defer = false, |
| 89 | .parent = &top_scope.base, | 90 | .parent = &top_scope.base, |
| 90 | .anon_name_strategy = .parent, | 91 | .anon_name_strategy = .parent, |
| 91 | .decl_node_index = 0, | 92 | .decl_node_index = 0, |
| ... | @@ -2118,14 +2119,20 @@ fn genDefers( | ... | @@ -2118,14 +2119,20 @@ fn genDefers( |
| 2118 | const defer_scope = scope.cast(Scope.Defer).?; | 2119 | const defer_scope = scope.cast(Scope.Defer).?; |
| 2119 | scope = defer_scope.parent; | 2120 | scope = defer_scope.parent; |
| 2120 | const expr_node = node_datas[defer_scope.defer_node].rhs; | 2121 | const expr_node = node_datas[defer_scope.defer_node].rhs; |
| | 2122 | const prev_in_defer = gz.in_defer; |
| | 2123 | gz.in_defer = true; |
| 2121 | try unusedResultExpr(gz, defer_scope.parent, expr_node); | 2124 | try unusedResultExpr(gz, defer_scope.parent, expr_node); |
| | 2125 | gz.in_defer = prev_in_defer; |
| 2122 | }, | 2126 | }, |
| 2123 | .defer_error => { | 2127 | .defer_error => { |
| 2124 | const defer_scope = scope.cast(Scope.Defer).?; | 2128 | const defer_scope = scope.cast(Scope.Defer).?; |
| 2125 | scope = defer_scope.parent; | 2129 | scope = defer_scope.parent; |
| 2126 | if (err_code == .none) continue; | 2130 | if (err_code == .none) continue; |
| 2127 | const expr_node = node_datas[defer_scope.defer_node].rhs; | 2131 | const expr_node = node_datas[defer_scope.defer_node].rhs; |
| | 2132 | const prev_in_defer = gz.in_defer; |
| | 2133 | gz.in_defer = true; |
| 2128 | try unusedResultExpr(gz, defer_scope.parent, expr_node); | 2134 | try unusedResultExpr(gz, defer_scope.parent, expr_node); |
| | 2135 | gz.in_defer = prev_in_defer; |
| 2129 | }, | 2136 | }, |
| 2130 | .namespace => unreachable, | 2137 | .namespace => unreachable, |
| 2131 | .top => unreachable, | 2138 | .top => unreachable, |
| ... | @@ -2728,6 +2735,7 @@ fn fnDecl( | ... | @@ -2728,6 +2735,7 @@ fn fnDecl( |
| 2728 | | 2735 | |
| 2729 | var decl_gz: GenZir = .{ | 2736 | var decl_gz: GenZir = .{ |
| 2730 | .force_comptime = true, | 2737 | .force_comptime = true, |
| | 2738 | .in_defer = false, |
| 2731 | .decl_node_index = fn_proto.ast.proto_node, | 2739 | .decl_node_index = fn_proto.ast.proto_node, |
| 2732 | .decl_line = gz.calcLine(decl_node), | 2740 | .decl_line = gz.calcLine(decl_node), |
| 2733 | .parent = scope, | 2741 | .parent = scope, |
| ... | @@ -2851,6 +2859,7 @@ fn fnDecl( | ... | @@ -2851,6 +2859,7 @@ fn fnDecl( |
| 2851 | | 2859 | |
| 2852 | var fn_gz: GenZir = .{ | 2860 | var fn_gz: GenZir = .{ |
| 2853 | .force_comptime = false, | 2861 | .force_comptime = false, |
| | 2862 | .in_defer = false, |
| 2854 | .decl_node_index = fn_proto.ast.proto_node, | 2863 | .decl_node_index = fn_proto.ast.proto_node, |
| 2855 | .decl_line = decl_gz.decl_line, | 2864 | .decl_line = decl_gz.decl_line, |
| 2856 | .parent = &decl_gz.base, | 2865 | .parent = &decl_gz.base, |
| ... | @@ -2981,6 +2990,7 @@ fn globalVarDecl( | ... | @@ -2981,6 +2990,7 @@ fn globalVarDecl( |
| 2981 | .decl_line = gz.calcLine(node), | 2990 | .decl_line = gz.calcLine(node), |
| 2982 | .astgen = astgen, | 2991 | .astgen = astgen, |
| 2983 | .force_comptime = true, | 2992 | .force_comptime = true, |
| | 2993 | .in_defer = false, |
| 2984 | .anon_name_strategy = .parent, | 2994 | .anon_name_strategy = .parent, |
| 2985 | }; | 2995 | }; |
| 2986 | defer block_scope.instructions.deinit(gpa); | 2996 | defer block_scope.instructions.deinit(gpa); |
| ... | @@ -3117,6 +3127,7 @@ fn comptimeDecl( | ... | @@ -3117,6 +3127,7 @@ fn comptimeDecl( |
| 3117 | | 3127 | |
| 3118 | var decl_block: GenZir = .{ | 3128 | var decl_block: GenZir = .{ |
| 3119 | .force_comptime = true, | 3129 | .force_comptime = true, |
| | 3130 | .in_defer = false, |
| 3120 | .decl_node_index = node, | 3131 | .decl_node_index = node, |
| 3121 | .decl_line = gz.calcLine(node), | 3132 | .decl_line = gz.calcLine(node), |
| 3122 | .parent = scope, | 3133 | .parent = scope, |
| ... | @@ -3169,6 +3180,7 @@ fn usingnamespaceDecl( | ... | @@ -3169,6 +3180,7 @@ fn usingnamespaceDecl( |
| 3169 | | 3180 | |
| 3170 | var decl_block: GenZir = .{ | 3181 | var decl_block: GenZir = .{ |
| 3171 | .force_comptime = true, | 3182 | .force_comptime = true, |
| | 3183 | .in_defer = false, |
| 3172 | .decl_node_index = node, | 3184 | .decl_node_index = node, |
| 3173 | .decl_line = gz.calcLine(node), | 3185 | .decl_line = gz.calcLine(node), |
| 3174 | .parent = scope, | 3186 | .parent = scope, |
| ... | @@ -3214,6 +3226,7 @@ fn testDecl( | ... | @@ -3214,6 +3226,7 @@ fn testDecl( |
| 3214 | | 3226 | |
| 3215 | var decl_block: GenZir = .{ | 3227 | var decl_block: GenZir = .{ |
| 3216 | .force_comptime = true, | 3228 | .force_comptime = true, |
| | 3229 | .in_defer = false, |
| 3217 | .decl_node_index = node, | 3230 | .decl_node_index = node, |
| 3218 | .decl_line = gz.calcLine(node), | 3231 | .decl_line = gz.calcLine(node), |
| 3219 | .parent = scope, | 3232 | .parent = scope, |
| ... | @@ -3235,6 +3248,7 @@ fn testDecl( | ... | @@ -3235,6 +3248,7 @@ fn testDecl( |
| 3235 | | 3248 | |
| 3236 | var fn_block: GenZir = .{ | 3249 | var fn_block: GenZir = .{ |
| 3237 | .force_comptime = false, | 3250 | .force_comptime = false, |
| | 3251 | .in_defer = false, |
| 3238 | .decl_node_index = node, | 3252 | .decl_node_index = node, |
| 3239 | .decl_line = decl_block.decl_line, | 3253 | .decl_line = decl_block.decl_line, |
| 3240 | .parent = &decl_block.base, | 3254 | .parent = &decl_block.base, |
| ... | @@ -3319,6 +3333,7 @@ fn structDeclInner( | ... | @@ -3319,6 +3333,7 @@ fn structDeclInner( |
| 3319 | .decl_line = gz.calcLine(node), | 3333 | .decl_line = gz.calcLine(node), |
| 3320 | .astgen = astgen, | 3334 | .astgen = astgen, |
| 3321 | .force_comptime = true, | 3335 | .force_comptime = true, |
| | 3336 | .in_defer = false, |
| 3322 | .ref_start_index = gz.ref_start_index, | 3337 | .ref_start_index = gz.ref_start_index, |
| 3323 | }; | 3338 | }; |
| 3324 | defer block_scope.instructions.deinit(gpa); | 3339 | defer block_scope.instructions.deinit(gpa); |
| ... | @@ -3580,6 +3595,7 @@ fn unionDeclInner( | ... | @@ -3580,6 +3595,7 @@ fn unionDeclInner( |
| 3580 | .decl_line = gz.calcLine(node), | 3595 | .decl_line = gz.calcLine(node), |
| 3581 | .astgen = astgen, | 3596 | .astgen = astgen, |
| 3582 | .force_comptime = true, | 3597 | .force_comptime = true, |
| | 3598 | .in_defer = false, |
| 3583 | .ref_start_index = gz.ref_start_index, | 3599 | .ref_start_index = gz.ref_start_index, |
| 3584 | }; | 3600 | }; |
| 3585 | defer block_scope.instructions.deinit(gpa); | 3601 | defer block_scope.instructions.deinit(gpa); |
| ... | @@ -3976,6 +3992,7 @@ fn containerDecl( | ... | @@ -3976,6 +3992,7 @@ fn containerDecl( |
| 3976 | .decl_line = gz.calcLine(node), | 3992 | .decl_line = gz.calcLine(node), |
| 3977 | .astgen = astgen, | 3993 | .astgen = astgen, |
| 3978 | .force_comptime = true, | 3994 | .force_comptime = true, |
| | 3995 | .in_defer = false, |
| 3979 | .ref_start_index = gz.ref_start_index, | 3996 | .ref_start_index = gz.ref_start_index, |
| 3980 | }; | 3997 | }; |
| 3981 | defer block_scope.instructions.deinit(gpa); | 3998 | defer block_scope.instructions.deinit(gpa); |
| ... | @@ -4432,6 +4449,8 @@ fn tryExpr( | ... | @@ -4432,6 +4449,8 @@ fn tryExpr( |
| 4432 | return astgen.failNode(node, "invalid 'try' outside function scope", .{}); | 4449 | return astgen.failNode(node, "invalid 'try' outside function scope", .{}); |
| 4433 | }; | 4450 | }; |
| 4434 | | 4451 | |
| | 4452 | if (parent_gz.in_defer) return astgen.failNode(node, "try is not allowed inside defer expression", .{}); |
| | 4453 | |
| 4435 | var block_scope = parent_gz.makeSubBlock(scope); | 4454 | var block_scope = parent_gz.makeSubBlock(scope); |
| 4436 | block_scope.setBreakResultLoc(rl); | 4455 | block_scope.setBreakResultLoc(rl); |
| 4437 | defer block_scope.instructions.deinit(astgen.gpa); | 4456 | defer block_scope.instructions.deinit(astgen.gpa); |
| ... | @@ -5962,6 +5981,8 @@ fn ret(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref | ... | @@ -5962,6 +5981,8 @@ fn ret(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref |
| 5962 | const node_datas = tree.nodes.items(.data); | 5981 | const node_datas = tree.nodes.items(.data); |
| 5963 | const main_tokens = tree.nodes.items(.main_token); | 5982 | const main_tokens = tree.nodes.items(.main_token); |
| 5964 | | 5983 | |
| | 5984 | if (gz.in_defer) return astgen.failNode(node, "cannot return from defer expression", .{}); |
| | 5985 | |
| 5965 | const operand_node = node_datas[node].lhs; | 5986 | const operand_node = node_datas[node].lhs; |
| 5966 | if (operand_node != 0) { | 5987 | if (operand_node != 0) { |
| 5967 | const rl: ResultLoc = if (nodeMayNeedMemoryLocation(tree, operand_node)) .{ | 5988 | const rl: ResultLoc = if (nodeMayNeedMemoryLocation(tree, operand_node)) .{ |
| ... | @@ -8040,6 +8061,7 @@ const GenZir = struct { | ... | @@ -8040,6 +8061,7 @@ const GenZir = struct { |
| 8040 | const base_tag: Scope.Tag = .gen_zir; | 8061 | const base_tag: Scope.Tag = .gen_zir; |
| 8041 | base: Scope = Scope{ .tag = base_tag }, | 8062 | base: Scope = Scope{ .tag = base_tag }, |
| 8042 | force_comptime: bool, | 8063 | force_comptime: bool, |
| | 8064 | in_defer: bool, |
| 8043 | /// How decls created in this scope should be named. | 8065 | /// How decls created in this scope should be named. |
| 8044 | anon_name_strategy: Zir.Inst.NameStrategy = .anon, | 8066 | anon_name_strategy: Zir.Inst.NameStrategy = .anon, |
| 8045 | /// The end of special indexes. `Zir.Inst.Ref` subtracts against this number to convert | 8067 | /// The end of special indexes. `Zir.Inst.Ref` subtracts against this number to convert |
| ... | @@ -8087,6 +8109,7 @@ const GenZir = struct { | ... | @@ -8087,6 +8109,7 @@ const GenZir = struct { |
| 8087 | fn makeSubBlock(gz: *GenZir, scope: *Scope) GenZir { | 8109 | fn makeSubBlock(gz: *GenZir, scope: *Scope) GenZir { |
| 8088 | return .{ | 8110 | return .{ |
| 8089 | .force_comptime = gz.force_comptime, | 8111 | .force_comptime = gz.force_comptime, |
| | 8112 | .in_defer = gz.in_defer, |
| 8090 | .ref_start_index = gz.ref_start_index, | 8113 | .ref_start_index = gz.ref_start_index, |
| 8091 | .decl_node_index = gz.decl_node_index, | 8114 | .decl_node_index = gz.decl_node_index, |
| 8092 | .decl_line = gz.decl_line, | 8115 | .decl_line = gz.decl_line, |