diff options
| author | jacob gw <jacoblevgw@gmail.com> | 2021-05-20 16:03:50 -0400 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-05-22 20:54:14 -0400 |
| commit | 9baf8917725ede02d9fc1aeebe253842174ee57b (patch) | |
| tree | 5d9d84872f1686e5b6986804f4cd7fad32713e93 /src/AstGen.zig | |
| parent | ceacb7d247950010bf42eb1390229c6fb808f949 (diff) | |
| download | zig-9baf8917725ede02d9fc1aeebe253842174ee57b.tar.gz zig-9baf8917725ede02d9fc1aeebe253842174ee57b.zip | |
stage2: astgen error for return or try in defer block
Diffstat (limited to 'src/AstGen.zig')
| -rw-r--r-- | src/AstGen.zig | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig index 8798c98021..fd2016aa11 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -86,6 +86,7 @@ pub fn generate(gpa: *Allocator, tree: ast.Tree) InnerError!Zir { var gen_scope: GenZir = .{ .force_comptime = true, + .in_defer = false, .parent = &top_scope.base, .anon_name_strategy = .parent, .decl_node_index = 0, @@ -2118,14 +2119,20 @@ fn genDefers( const defer_scope = scope.cast(Scope.Defer).?; scope = defer_scope.parent; const expr_node = node_datas[defer_scope.defer_node].rhs; + const prev_in_defer = gz.in_defer; + gz.in_defer = true; try unusedResultExpr(gz, defer_scope.parent, expr_node); + gz.in_defer = prev_in_defer; }, .defer_error => { const defer_scope = scope.cast(Scope.Defer).?; scope = defer_scope.parent; if (err_code == .none) continue; const expr_node = node_datas[defer_scope.defer_node].rhs; + const prev_in_defer = gz.in_defer; + gz.in_defer = true; try unusedResultExpr(gz, defer_scope.parent, expr_node); + gz.in_defer = prev_in_defer; }, .namespace => unreachable, .top => unreachable, @@ -2728,6 +2735,7 @@ fn fnDecl( var decl_gz: GenZir = .{ .force_comptime = true, + .in_defer = false, .decl_node_index = fn_proto.ast.proto_node, .decl_line = gz.calcLine(decl_node), .parent = scope, @@ -2851,6 +2859,7 @@ fn fnDecl( var fn_gz: GenZir = .{ .force_comptime = false, + .in_defer = false, .decl_node_index = fn_proto.ast.proto_node, .decl_line = decl_gz.decl_line, .parent = &decl_gz.base, @@ -2981,6 +2990,7 @@ fn globalVarDecl( .decl_line = gz.calcLine(node), .astgen = astgen, .force_comptime = true, + .in_defer = false, .anon_name_strategy = .parent, }; defer block_scope.instructions.deinit(gpa); @@ -3117,6 +3127,7 @@ fn comptimeDecl( var decl_block: GenZir = .{ .force_comptime = true, + .in_defer = false, .decl_node_index = node, .decl_line = gz.calcLine(node), .parent = scope, @@ -3169,6 +3180,7 @@ fn usingnamespaceDecl( var decl_block: GenZir = .{ .force_comptime = true, + .in_defer = false, .decl_node_index = node, .decl_line = gz.calcLine(node), .parent = scope, @@ -3214,6 +3226,7 @@ fn testDecl( var decl_block: GenZir = .{ .force_comptime = true, + .in_defer = false, .decl_node_index = node, .decl_line = gz.calcLine(node), .parent = scope, @@ -3235,6 +3248,7 @@ fn testDecl( var fn_block: GenZir = .{ .force_comptime = false, + .in_defer = false, .decl_node_index = node, .decl_line = decl_block.decl_line, .parent = &decl_block.base, @@ -3319,6 +3333,7 @@ fn structDeclInner( .decl_line = gz.calcLine(node), .astgen = astgen, .force_comptime = true, + .in_defer = false, .ref_start_index = gz.ref_start_index, }; defer block_scope.instructions.deinit(gpa); @@ -3580,6 +3595,7 @@ fn unionDeclInner( .decl_line = gz.calcLine(node), .astgen = astgen, .force_comptime = true, + .in_defer = false, .ref_start_index = gz.ref_start_index, }; defer block_scope.instructions.deinit(gpa); @@ -3976,6 +3992,7 @@ fn containerDecl( .decl_line = gz.calcLine(node), .astgen = astgen, .force_comptime = true, + .in_defer = false, .ref_start_index = gz.ref_start_index, }; defer block_scope.instructions.deinit(gpa); @@ -4432,6 +4449,8 @@ fn tryExpr( return astgen.failNode(node, "invalid 'try' outside function scope", .{}); }; + if (parent_gz.in_defer) return astgen.failNode(node, "try is not allowed inside defer expression", .{}); + var block_scope = parent_gz.makeSubBlock(scope); block_scope.setBreakResultLoc(rl); 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 const node_datas = tree.nodes.items(.data); const main_tokens = tree.nodes.items(.main_token); + if (gz.in_defer) return astgen.failNode(node, "cannot return from defer expression", .{}); + const operand_node = node_datas[node].lhs; if (operand_node != 0) { const rl: ResultLoc = if (nodeMayNeedMemoryLocation(tree, operand_node)) .{ @@ -8040,6 +8061,7 @@ const GenZir = struct { const base_tag: Scope.Tag = .gen_zir; base: Scope = Scope{ .tag = base_tag }, force_comptime: bool, + in_defer: bool, /// How decls created in this scope should be named. anon_name_strategy: Zir.Inst.NameStrategy = .anon, /// The end of special indexes. `Zir.Inst.Ref` subtracts against this number to convert @@ -8087,6 +8109,7 @@ const GenZir = struct { fn makeSubBlock(gz: *GenZir, scope: *Scope) GenZir { return .{ .force_comptime = gz.force_comptime, + .in_defer = gz.in_defer, .ref_start_index = gz.ref_start_index, .decl_node_index = gz.decl_node_index, .decl_line = gz.decl_line, |
