authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-08-02 21:01:20+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-08-03 16:45:33+03:00
logb79929b2eaa634b756fe374372d59718f4f8479a
treeef77bc8ee5261c8733b0558ecee0d1bed08e57bf
parentd1d24b426dd8f12e6d643f45fcb6bb11dddaa8ef

AstGen: better source location for if/while condition unwrapping


19 files changed, 130 insertions(+), 127 deletions(-)

src/AstGen.zig+11-10
...@@ -2696,6 +2696,7 @@ fn genDefers(...@@ -2696,6 +2696,7 @@ fn genDefers(
2696 break :blk &local_val_scope.base;2696 break :blk &local_val_scope.base;
2697 };2697 };
2698 try unusedResultDeferExpr(gz, defer_scope, sub_scope, expr_node);2698 try unusedResultDeferExpr(gz, defer_scope, sub_scope, expr_node);
2699 try checkUsed(gz, scope, sub_scope);
2699 try gz.addDbgBlockEnd();2700 try gz.addDbgBlockEnd();
2700 },2701 },
2701 .normal_only => continue,2702 .normal_only => continue,
...@@ -5384,7 +5385,7 @@ fn ifExpr(...@@ -5384,7 +5385,7 @@ fn ifExpr(
5384 const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_err_ptr else .is_non_err;5385 const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_err_ptr else .is_non_err;
5385 break :c .{5386 break :c .{
5386 .inst = err_union,5387 .inst = err_union,
5387 .bool_bit = try block_scope.addUnNode(tag, err_union, node),5388 .bool_bit = try block_scope.addUnNode(tag, err_union, if_full.ast.cond_expr),
5388 };5389 };
5389 } else if (if_full.payload_token) |_| {5390 } else if (if_full.payload_token) |_| {
5390 const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none;5391 const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none;
...@@ -5392,7 +5393,7 @@ fn ifExpr(...@@ -5392,7 +5393,7 @@ fn ifExpr(
5392 const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_null_ptr else .is_non_null;5393 const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_null_ptr else .is_non_null;
5393 break :c .{5394 break :c .{
5394 .inst = optional,5395 .inst = optional,
5395 .bool_bit = try block_scope.addUnNode(tag, optional, node),5396 .bool_bit = try block_scope.addUnNode(tag, optional, if_full.ast.cond_expr),
5396 };5397 };
5397 } else {5398 } else {
5398 const cond = try expr(&block_scope, &block_scope.base, bool_rl, if_full.ast.cond_expr);5399 const cond = try expr(&block_scope, &block_scope.base, bool_rl, if_full.ast.cond_expr);
...@@ -5423,7 +5424,7 @@ fn ifExpr(...@@ -5423,7 +5424,7 @@ fn ifExpr(
5423 .err_union_payload_unsafe_ptr5424 .err_union_payload_unsafe_ptr
5424 else5425 else
5425 .err_union_payload_unsafe;5426 .err_union_payload_unsafe;
5426 const payload_inst = try then_scope.addUnNode(tag, cond.inst, node);5427 const payload_inst = try then_scope.addUnNode(tag, cond.inst, if_full.ast.then_expr);
5427 const token_name_index = payload_token + @boolToInt(payload_is_ref);5428 const token_name_index = payload_token + @boolToInt(payload_is_ref);
5428 const ident_name = try astgen.identAsString(token_name_index);5429 const ident_name = try astgen.identAsString(token_name_index);
5429 const token_name_str = tree.tokenSlice(token_name_index);5430 const token_name_str = tree.tokenSlice(token_name_index);
...@@ -5452,7 +5453,7 @@ fn ifExpr(...@@ -5452,7 +5453,7 @@ fn ifExpr(
5452 const ident_bytes = tree.tokenSlice(ident_token);5453 const ident_bytes = tree.tokenSlice(ident_token);
5453 if (mem.eql(u8, "_", ident_bytes))5454 if (mem.eql(u8, "_", ident_bytes))
5454 break :s &then_scope.base;5455 break :s &then_scope.base;
5455 const payload_inst = try then_scope.addUnNode(tag, cond.inst, node);5456 const payload_inst = try then_scope.addUnNode(tag, cond.inst, if_full.ast.then_expr);
5456 const ident_name = try astgen.identAsString(ident_token);5457 const ident_name = try astgen.identAsString(ident_token);
5457 try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes);5458 try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes);
5458 payload_val_scope = .{5459 payload_val_scope = .{
...@@ -5495,7 +5496,7 @@ fn ifExpr(...@@ -5495,7 +5496,7 @@ fn ifExpr(
5495 .err_union_code_ptr5496 .err_union_code_ptr
5496 else5497 else
5497 .err_union_code;5498 .err_union_code;
5498 const payload_inst = try else_scope.addUnNode(tag, cond.inst, node);5499 const payload_inst = try else_scope.addUnNode(tag, cond.inst, if_full.ast.cond_expr);
5499 const ident_name = try astgen.identAsString(error_token);5500 const ident_name = try astgen.identAsString(error_token);
5500 const error_token_str = tree.tokenSlice(error_token);5501 const error_token_str = tree.tokenSlice(error_token);
5501 if (mem.eql(u8, "_", error_token_str))5502 if (mem.eql(u8, "_", error_token_str))
...@@ -5709,7 +5710,7 @@ fn whileExpr(...@@ -5709,7 +5710,7 @@ fn whileExpr(
5709 const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_err_ptr else .is_non_err;5710 const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_err_ptr else .is_non_err;
5710 break :c .{5711 break :c .{
5711 .inst = err_union,5712 .inst = err_union,
5712 .bool_bit = try continue_scope.addUnNode(tag, err_union, node),5713 .bool_bit = try continue_scope.addUnNode(tag, err_union, while_full.ast.then_expr),
5713 };5714 };
5714 } else if (while_full.payload_token) |_| {5715 } else if (while_full.payload_token) |_| {
5715 const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none;5716 const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none;
...@@ -5717,7 +5718,7 @@ fn whileExpr(...@@ -5717,7 +5718,7 @@ fn whileExpr(
5717 const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_null_ptr else .is_non_null;5718 const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_null_ptr else .is_non_null;
5718 break :c .{5719 break :c .{
5719 .inst = optional,5720 .inst = optional,
5720 .bool_bit = try continue_scope.addUnNode(tag, optional, node),5721 .bool_bit = try continue_scope.addUnNode(tag, optional, while_full.ast.then_expr),
5721 };5722 };
5722 } else {5723 } else {
5723 const cond = try expr(&continue_scope, &continue_scope.base, bool_rl, while_full.ast.cond_expr);5724 const cond = try expr(&continue_scope, &continue_scope.base, bool_rl, while_full.ast.cond_expr);
...@@ -5755,7 +5756,7 @@ fn whileExpr(...@@ -5755,7 +5756,7 @@ fn whileExpr(
5755 else5756 else
5756 .err_union_payload_unsafe;5757 .err_union_payload_unsafe;
5757 // will add this instruction to then_scope.instructions below5758 // will add this instruction to then_scope.instructions below
5758 payload_inst = try then_scope.makeUnNode(tag, cond.inst, node);5759 payload_inst = try then_scope.makeUnNode(tag, cond.inst, while_full.ast.cond_expr);
5759 const ident_token = if (payload_is_ref) payload_token + 1 else payload_token;5760 const ident_token = if (payload_is_ref) payload_token + 1 else payload_token;
5760 const ident_bytes = tree.tokenSlice(ident_token);5761 const ident_bytes = tree.tokenSlice(ident_token);
5761 if (mem.eql(u8, "_", ident_bytes))5762 if (mem.eql(u8, "_", ident_bytes))
...@@ -5784,7 +5785,7 @@ fn whileExpr(...@@ -5784,7 +5785,7 @@ fn whileExpr(
5784 else5785 else
5785 .optional_payload_unsafe;5786 .optional_payload_unsafe;
5786 // will add this instruction to then_scope.instructions below5787 // will add this instruction to then_scope.instructions below
5787 payload_inst = try then_scope.makeUnNode(tag, cond.inst, node);5788 payload_inst = try then_scope.makeUnNode(tag, cond.inst, while_full.ast.cond_expr);
5788 const ident_name = try astgen.identAsString(ident_token);5789 const ident_name = try astgen.identAsString(ident_token);
5789 const ident_bytes = tree.tokenSlice(ident_token);5790 const ident_bytes = tree.tokenSlice(ident_token);
5790 if (mem.eql(u8, "_", ident_bytes))5791 if (mem.eql(u8, "_", ident_bytes))
...@@ -5860,7 +5861,7 @@ fn whileExpr(...@@ -5860,7 +5861,7 @@ fn whileExpr(
5860 .err_union_code_ptr5861 .err_union_code_ptr
5861 else5862 else
5862 .err_union_code;5863 .err_union_code;
5863 const else_payload_inst = try else_scope.addUnNode(tag, cond.inst, node);5864 const else_payload_inst = try else_scope.addUnNode(tag, cond.inst, while_full.ast.cond_expr);
5864 const ident_name = try astgen.identAsString(error_token);5865 const ident_name = try astgen.identAsString(error_token);
5865 const ident_bytes = tree.tokenSlice(error_token);5866 const ident_bytes = tree.tokenSlice(error_token);
5866 if (mem.eql(u8, ident_bytes, "_"))5867 if (mem.eql(u8, ident_bytes, "_"))
test/cases/compile_errors/packed_union_given_enum_tag_type.zig created+20
...@@ -0,0 +1,20 @@
1const Letter = enum {
2 A,
3 B,
4 C,
5};
6const Payload = packed union(Letter) {
7 A: i32,
8 B: f64,
9 C: bool,
10};
11export fn entry() void {
12 var a = Payload { .A = 1234 };
13 _ = a;
14}
15
16// error
17// backend=stage2
18// target=native
19//
20// :6:30: error: packed union does not support enum tag type
test/cases/compile_errors/packed_union_with_automatic_layout_field.zig created+20
...@@ -0,0 +1,20 @@
1const Foo = struct {
2 a: u32,
3 b: f32,
4};
5const Payload = packed union {
6 A: Foo,
7 B: bool,
8};
9export fn entry() void {
10 var a = Payload { .B = true };
11 _ = a;
12}
13
14// error
15// backend=stage2
16// target=native
17//
18// :6:5: error: packed unions cannot contain fields of type 'tmp.Foo'
19// :6:5: note: only packed structs layout are allowed in packed types
20// :1:13: note: struct declared here
test/cases/compile_errors/specify_non-integer_enum_tag_type.zig created+16
...@@ -0,0 +1,16 @@
1const Small = enum (f32) {
2 One,
3 Two,
4 Three,
5};
6
7export fn entry() void {
8 var x = Small.One;
9 _ = x;
10}
11
12// error
13// backend=stage2
14// target=native
15//
16// :1:21: error: expected integer tag type, found 'f32'
test/cases/compile_errors/stage1/obj/packed_union_given_enum_tag_type.zig deleted-20
...@@ -1,20 +0,0 @@
1const Letter = enum {
2 A,
3 B,
4 C,
5};
6const Payload = packed union(Letter) {
7 A: i32,
8 B: f64,
9 C: bool,
10};
11export fn entry() void {
12 var a = Payload { .A = 1234 };
13 _ = a;
14}
15
16// error
17// backend=stage1
18// target=native
19//
20// tmp.zig:6:30: error: packed union does not support enum tag type
test/cases/compile_errors/stage1/obj/packed_union_with_automatic_layout_field.zig deleted-18
...@@ -1,18 +0,0 @@
1const Foo = struct {
2 a: u32,
3 b: f32,
4};
5const Payload = packed union {
6 A: Foo,
7 B: bool,
8};
9export fn entry() void {
10 var a = Payload { .B = true };
11 _ = a;
12}
13
14// error
15// backend=stage1
16// target=native
17//
18// tmp.zig:6:5: error: non-packed, non-extern struct 'Foo' not allowed in packed union; no guaranteed in-memory representation
test/cases/compile_errors/stage1/obj/specify_non-integer_enum_tag_type.zig deleted-16
...@@ -1,16 +0,0 @@
1const Small = enum (f32) {
2 One,
3 Two,
4 Three,
5};
6
7export fn entry() void {
8 var x = Small.One;
9 _ = x;
10}
11
12// error
13// backend=stage1
14// target=native
15//
16// tmp.zig:1:21: error: expected integer, found 'f32'
test/cases/compile_errors/stage1/obj/unused_variable_error_on_errdefer.zig deleted-13
...@@ -1,13 +0,0 @@
1fn foo() !void {
2 errdefer |a| unreachable;
3 return error.A;
4}
5export fn entry() void {
6 foo() catch unreachable;
7}
8
9// error
10// backend=stage1
11// target=native
12//
13// tmp.zig:2:15: error: unused variable: 'a'
test/cases/compile_errors/stage1/obj/vector_index_out_of_bounds.zig deleted-10
...@@ -1,10 +0,0 @@
1export fn entry() void {
2 const x = @import("std").meta.Vector(3, f32){ 25, 75, 5, 0 };
3 _ = x;
4}
5
6// error
7// backend=stage1
8// target=native
9//
10// tmp.zig:2:62: error: index 3 outside vector of size 3
test/cases/compile_errors/stage1/obj/while_expected_error_union_got_bool.zig deleted-10
...@@ -1,10 +0,0 @@
1export fn foo() void {
2 while (bar()) |x| {_ = x;} else |err| {_ = err;}
3}
4fn bar() bool { return true; }
5
6// error
7// backend=stage1
8// target=native
9//
10// tmp.zig:2:15: error: expected error union type, found 'bool'
test/cases/compile_errors/stage1/obj/while_expected_error_union_got_optional.zig deleted-10
...@@ -1,10 +0,0 @@
1export fn foo() void {
2 while (bar()) |x| {_ = x;} else |err| {_ = err;}
3}
4fn bar() ?i32 { return 1; }
5
6// error
7// backend=stage1
8// target=native
9//
10// tmp.zig:2:15: error: expected error union type, found '?i32'
test/cases/compile_errors/stage1/obj/while_expected_optional_got_bool.zig deleted-10
...@@ -1,10 +0,0 @@
1export fn foo() void {
2 while (bar()) |x| {_ = x;}
3}
4fn bar() bool { return true; }
5
6// error
7// backend=stage1
8// target=native
9//
10// tmp.zig:2:15: error: expected optional type, found 'bool'
test/cases/compile_errors/stage1/obj/while_expected_optional_got_error_union.zig deleted-10
...@@ -1,10 +0,0 @@
1export fn foo() void {
2 while (bar()) |x| {_ = x;}
3}
4fn bar() anyerror!i32 { return 1; }
5
6// error
7// backend=stage1
8// target=native
9//
10// tmp.zig:2:15: error: expected optional type, found 'anyerror!i32'
test/cases/compile_errors/unused_variable_error_on_errdefer.zig created+13
...@@ -0,0 +1,13 @@
1fn foo() !void {
2 errdefer |a| unreachable;
3 return error.A;
4}
5export fn entry() void {
6 foo() catch unreachable;
7}
8
9// error
10// backend=stage2
11// target=native
12//
13// :2:15: error: unused capture
test/cases/compile_errors/vector_index_out_of_bounds.zig created+10
...@@ -0,0 +1,10 @@
1export fn entry() void {
2 const x = @import("std").meta.Vector(3, f32){ 25, 75, 5, 0 };
3 _ = x;
4}
5
6// error
7// backend=stage2
8// target=native
9//
10// :2:49: error: expected 3 vector elements; found 4
test/cases/compile_errors/while_expected_error_union_got_bool.zig created+10
...@@ -0,0 +1,10 @@
1export fn foo() void {
2 while (bar()) |x| {_ = x;} else |err| {_ = err;}
3}
4fn bar() bool { return true; }
5
6// error
7// backend=stage2
8// target=native
9//
10// :2:15: error: expected error union type, found 'bool'
test/cases/compile_errors/while_expected_error_union_got_optional.zig created+10
...@@ -0,0 +1,10 @@
1export fn foo() void {
2 while (bar()) |x| {_ = x;} else |err| {_ = err;}
3}
4fn bar() ?i32 { return 1; }
5
6// error
7// backend=stage2
8// target=native
9//
10// :2:15: error: expected error union type, found '?i32'
test/cases/compile_errors/while_expected_optional_got_bool.zig created+10
...@@ -0,0 +1,10 @@
1export fn foo() void {
2 while (bar()) |x| {_ = x;}
3}
4fn bar() bool { return true; }
5
6// error
7// backend=stage2
8// target=native
9//
10// :2:15: error: expected optional type, found 'bool'
test/cases/compile_errors/while_expected_optional_got_error_union.zig created+10
...@@ -0,0 +1,10 @@
1export fn foo() void {
2 while (bar()) |x| {_ = x;}
3}
4fn bar() anyerror!i32 { return 1; }
5
6// error
7// backend=stage2
8// target=native
9//
10// :2:15: error: expected optional type, found 'anyerror!i32'