authorgravatar for jacoblevgw@gmail.comJacob G-W <jacoblevgw@gmail.com> 2021-05-20 16:03:50-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-22 20:54:14-04:00
log9baf8917725ede02d9fc1aeebe253842174ee57b
tree5d9d84872f1686e5b6986804f4cd7fad32713e93
parentceacb7d247950010bf42eb1390229c6fb808f949

stage2: astgen error for return or try in defer block


2 files changed, 41 insertions(+), 0 deletions(-)

src/AstGen.zig+23
...@@ -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 {
8686
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(
27282735
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(
28512859
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(
31173127
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(
31693180
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(
32143226
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(
32353248
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 };
44344451
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);
59645983
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 convert8067 /// 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,
test/stage2/test.zig+18
...@@ -926,6 +926,24 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -926,6 +926,24 @@ pub fn addCases(ctx: *TestContext) !void {
926 ":5:1: note: declared here",926 ":5:1: note: declared here",
927 });927 });
928928
929 ctx.compileError("returns in try", linux_x64,
930 \\pub fn main() !void {
931 \\ try a();
932 \\ try b();
933 \\}
934 \\
935 \\pub fn a() !void {
936 \\ defer try b();
937 \\}
938 \\pub fn b() !void {
939 \\ defer return a();
940 \\}
941
942 , &[_][]const u8{
943 ":7:8: error: try is not allowed inside defer expression",
944 ":10:8: error: cannot return from defer expression",
945 });
946
929 ctx.compileError("global variable redeclaration", linux_x64,947 ctx.compileError("global variable redeclaration", linux_x64,
930 \\// dummy comment948 \\// dummy comment
931 \\var foo = false;949 \\var foo = false;