diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-05-28 17:29:56 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-05-28 17:29:56 -0700 |
| commit | 3f5ca3920a58d44a018ff2a2e277e60813e20d5a (patch) | |
| tree | ff156147167ab13852411e5b2e9a6eed51ab88d0 /src/AstGen.zig | |
| parent | 54f774f7966e48a8419dbe2d3b37ae974ec03a83 (diff) | |
| download | zig-3f5ca3920a58d44a018ff2a2e277e60813e20d5a.tar.gz zig-3f5ca3920a58d44a018ff2a2e277e60813e20d5a.zip | |
AstGen: properly restore previous state after temporary changes
Before this, if a compile error occurred, it would cause the previous
value for e.g. the function scope to not get reset. If the AstGen
process continued, it would result in a violation of the data
guarantees that it relies on.
This commit takes advantage of defer to ensure the previous value is
always reset, even in the case of an error.
Closes #8920
Diffstat (limited to 'src/AstGen.zig')
| -rw-r--r-- | src/AstGen.zig | 22 |
1 files changed, 10 insertions, 12 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig index baa45493d6..790984dc8f 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -249,9 +249,9 @@ pub const bool_rl: ResultLoc = .{ .ty = .bool_type }; fn typeExpr(gz: *GenZir, scope: *Scope, type_node: ast.Node.Index) InnerError!Zir.Inst.Ref { const prev_force_comptime = gz.force_comptime; gz.force_comptime = true; - const e = expr(gz, scope, .{ .ty = .type_type }, type_node); - gz.force_comptime = prev_force_comptime; - return e; + defer gz.force_comptime = prev_force_comptime; + + return expr(gz, scope, .{ .ty = .type_type }, type_node); } fn lvalExpr(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref { @@ -1465,9 +1465,9 @@ fn comptimeExpr( ) InnerError!Zir.Inst.Ref { const prev_force_comptime = gz.force_comptime; gz.force_comptime = true; - const result = try expr(gz, scope, rl, node); - gz.force_comptime = prev_force_comptime; - return result; + defer gz.force_comptime = prev_force_comptime; + + return expr(gz, scope, rl, node); } /// This one is for an actual `comptime` syntax, and will emit a compile error if @@ -2121,8 +2121,8 @@ fn genDefers( const expr_node = node_datas[defer_scope.defer_node].rhs; const prev_in_defer = gz.in_defer; gz.in_defer = true; + defer gz.in_defer = prev_in_defer; try unusedResultExpr(gz, defer_scope.parent, expr_node); - gz.in_defer = prev_in_defer; }, .defer_error => { const defer_scope = scope.cast(Scope.Defer).?; @@ -2131,8 +2131,8 @@ fn genDefers( const expr_node = node_datas[defer_scope.defer_node].rhs; const prev_in_defer = gz.in_defer; gz.in_defer = true; + defer gz.in_defer = prev_in_defer; try unusedResultExpr(gz, defer_scope.parent, expr_node); - gz.in_defer = prev_in_defer; }, .namespace => unreachable, .top => unreachable, @@ -2887,6 +2887,7 @@ fn fnDecl( const prev_fn_block = astgen.fn_block; astgen.fn_block = &fn_gz; + defer astgen.fn_block = prev_fn_block; // Iterate over the parameters. We put the param names as the first N // items inside `extra` so that debug info later can refer to the parameter names @@ -2938,8 +2939,6 @@ fn fnDecl( _ = try fn_gz.addUnTok(.ret_coerce, .void_value, tree.lastToken(body_node)); } - astgen.fn_block = prev_fn_block; - break :func try decl_gz.addFunc(.{ .src_node = decl_node, .ret_ty = return_type_inst, @@ -3276,6 +3275,7 @@ fn testDecl( const prev_fn_block = astgen.fn_block; astgen.fn_block = &fn_block; + defer astgen.fn_block = prev_fn_block; const block_result = try expr(&fn_block, &fn_block.base, .none, body_node); if (fn_block.instructions.items.len == 0 or !fn_block.refIsNoReturn(block_result)) { @@ -3284,8 +3284,6 @@ fn testDecl( _ = try fn_block.addUnTok(.ret_coerce, .void_value, tree.lastToken(body_node)); } - astgen.fn_block = prev_fn_block; - const func_inst = try decl_block.addFunc(.{ .src_node = node, .ret_ty = .void_type, |
