authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-01 15:42:21-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-02 13:27:35-07:00
logabfee127353cbdadab4282b61056222cdfbec2d4
treeabcb5e07640b1cf3b426dbbfc7b115bf536ea20e
parent24c432608f6b07020fa0b18fc9c868ad6abd9b15

AstGen: pass more compile error tests

* Implement "initializing array with struct syntax" * Implement "'_' used as an identifier without @\"_\" syntax" * Fix source location of "missing parameter name" * Update test cases where appropriate

2 files changed, 50 insertions(+), 26 deletions(-)

src/AstGen.zig+36-19
......@@ -1313,22 +1313,23 @@ fn structInitExpr(
13131313 const astgen = gz.astgen;
13141314 const tree = astgen.tree;
13151315
1316 if (struct_init.ast.fields.len == 0) {
1317 if (struct_init.ast.type_expr == 0) {
1316 if (struct_init.ast.type_expr == 0) {
1317 if (struct_init.ast.fields.len == 0) {
13181318 return rvalue(gz, rl, .empty_struct, node);
13191319 }
1320 array: {
1321 const node_tags = tree.nodes.items(.tag);
1322 const main_tokens = tree.nodes.items(.main_token);
1323 const array_type: ast.full.ArrayType = switch (node_tags[struct_init.ast.type_expr]) {
1324 .array_type => tree.arrayType(struct_init.ast.type_expr),
1325 .array_type_sentinel => tree.arrayTypeSentinel(struct_init.ast.type_expr),
1326 else => break :array,
1327 };
1320 } else array: {
1321 const node_tags = tree.nodes.items(.tag);
1322 const main_tokens = tree.nodes.items(.main_token);
1323 const array_type: ast.full.ArrayType = switch (node_tags[struct_init.ast.type_expr]) {
1324 .array_type => tree.arrayType(struct_init.ast.type_expr),
1325 .array_type_sentinel => tree.arrayTypeSentinel(struct_init.ast.type_expr),
1326 else => break :array,
1327 };
1328 const is_inferred_array_len = node_tags[array_type.ast.elem_count] == .identifier and
13281329 // This intentionally does not support `@"_"` syntax.
1329 if (node_tags[array_type.ast.elem_count] == .identifier and
1330 mem.eql(u8, tree.tokenSlice(main_tokens[array_type.ast.elem_count]), "_"))
1331 {
1330 mem.eql(u8, tree.tokenSlice(main_tokens[array_type.ast.elem_count]), "_");
1331 if (struct_init.ast.fields.len == 0) {
1332 if (is_inferred_array_len) {
13321333 const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type);
13331334 const array_type_inst = if (array_type.ast.sentinel == 0) blk: {
13341335 break :blk try gz.addBin(.array_type, .zero_usize, elem_type);
......@@ -1339,11 +1340,18 @@ fn structInitExpr(
13391340 const result = try gz.addUnNode(.struct_init_empty, array_type_inst, node);
13401341 return rvalue(gz, rl, result, node);
13411342 }
1343 const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
1344 const result = try gz.addUnNode(.struct_init_empty, ty_inst, node);
1345 return rvalue(gz, rl, result, node);
1346 } else {
1347 return astgen.failNode(
1348 struct_init.ast.type_expr,
1349 "initializing array with struct syntax",
1350 .{},
1351 );
13421352 }
1343 const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
1344 const result = try gz.addUnNode(.struct_init_empty, ty_inst, node);
1345 return rvalue(gz, rl, result, node);
13461353 }
1354
13471355 switch (rl) {
13481356 .discard => {
13491357 if (struct_init.ast.type_expr != 0)
......@@ -2266,6 +2274,10 @@ fn varDecl(
22662274 const token_tags = tree.tokens.items(.tag);
22672275
22682276 const name_token = var_decl.ast.mut_token + 1;
2277 const ident_name_raw = tree.tokenSlice(name_token);
2278 if (mem.eql(u8, ident_name_raw, "_")) {
2279 return astgen.failTok(name_token, "'_' used as an identifier without @\"_\" syntax", .{});
2280 }
22692281 const ident_name = try astgen.identAsString(name_token);
22702282
22712283 // Local variables shadowing detection, including function parameters.
......@@ -3003,7 +3015,11 @@ fn fnDecl(
30033015 var it = fn_proto.iterate(tree.*);
30043016 while (it.next()) |param| : (i += 1) {
30053017 const name_token = param.name_token orelse {
3006 return astgen.failNode(param.type_expr, "missing parameter name", .{});
3018 if (param.anytype_ellipsis3) |tok| {
3019 return astgen.failTok(tok, "missing parameter name", .{});
3020 } else {
3021 return astgen.failNode(param.type_expr, "missing parameter name", .{});
3022 }
30073023 };
30083024 if (param.type_expr != 0)
30093025 _ = try typeExpr(&fn_gz, params_scope, param.type_expr);
......@@ -6197,10 +6213,11 @@ fn identifier(
61976213 const main_tokens = tree.nodes.items(.main_token);
61986214
61996215 const ident_token = main_tokens[ident];
6200 const ident_name = try astgen.identifierTokenString(ident_token);
6201 if (mem.eql(u8, ident_name, "_")) {
6216 const ident_name_raw = tree.tokenSlice(ident_token);
6217 if (mem.eql(u8, ident_name_raw, "_")) {
62026218 return astgen.failNode(ident, "'_' used as an identifier without @\"_\" syntax", .{});
62036219 }
6220 const ident_name = try astgen.identifierTokenString(ident_token);
62046221
62056222 if (simple_types.get(ident_name)) |zir_const_ref| {
62066223 return rvalue(gz, rl, zir_const_ref, ident);
test/compile_errors.zig+14-7
......@@ -2130,8 +2130,7 @@ pub fn addCases(ctx: *TestContext) !void {
21302130 \\ _ = x;
21312131 \\}
21322132 , &[_][]const u8{
2133 "tmp.zig:3:13: error: structs and unions, not enums, support field alignment",
2134 "tmp.zig:1:16: note: consider 'union(enum)' here",
2133 "tmp.zig:3:7: error: expected ',', found 'align'",
21352134 });
21362135
21372136 ctx.objErrStage1("bad alignment type",
......@@ -3765,8 +3764,7 @@ pub fn addCases(ctx: *TestContext) !void {
37653764 \\ return _;
37663765 \\}
37673766 , &[_][]const u8{
3768 "tmp.zig:2:5: error: '_' used as an identifier without @\"_\" syntax",
3769 "tmp.zig:3:12: error: '_' used as an identifier without @\"_\" syntax",
3767 "tmp.zig:2:9: error: '_' used as an identifier without @\"_\" syntax",
37703768 });
37713769
37723770 ctx.objErrStage1("`_` should not be usable inside for",
......@@ -4908,7 +4906,7 @@ pub fn addCases(ctx: *TestContext) !void {
49084906 \\export fn entry() void { a(); }
49094907 , &[_][]const u8{
49104908 "tmp.zig:2:1: error: redeclaration of 'a'",
4911 "tmp.zig:1:1: error: other declaration here",
4909 "tmp.zig:1:1: note: other declaration here",
49124910 });
49134911
49144912 ctx.objErrStage1("unreachable with return",
......@@ -5218,6 +5216,7 @@ pub fn addCases(ctx: *TestContext) !void {
52185216 \\ .z = 4,
52195217 \\ .y = 2,
52205218 \\ };
5219 \\ _ = a;
52215220 \\}
52225221 , &[_][]const u8{
52235222 "tmp.zig:9:17: error: missing field: 'x'",
......@@ -7549,13 +7548,15 @@ pub fn addCases(ctx: *TestContext) !void {
75497548 \\ };
75507549 \\
75517550 \\ for ([_]Mode { Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast }) |mode| {
7551 \\ _ = mode;
75527552 \\ inline for (tests) |test_case| {
75537553 \\ const foo = test_case.filename ++ ".zig";
7554 \\ _ = foo;
75547555 \\ }
75557556 \\ }
75567557 \\}
75577558 , &[_][]const u8{
7558 "tmp.zig:37:29: error: cannot store runtime value in compile time variable",
7559 "tmp.zig:38:29: error: cannot store runtime value in compile time variable",
75597560 });
75607561
75617562 ctx.objErrStage1("invalid legacy unicode escape",
......@@ -7980,6 +7981,7 @@ pub fn addCases(ctx: *TestContext) !void {
79807981 \\};
79817982 \\export fn foo() void {
79827983 \\ const fieldOffset = @offsetOf(Empty, "val",);
7984 \\ _ = fieldOffset;
79837985 \\}
79847986 , &[_][]const u8{
79857987 "tmp.zig:5:42: error: zero-bit field 'val' in struct 'Empty' has no offset",
......@@ -7991,6 +7993,7 @@ pub fn addCases(ctx: *TestContext) !void {
79917993 \\};
79927994 \\export fn foo() void {
79937995 \\ const fieldOffset = @bitOffsetOf(Empty, "val",);
7996 \\ _ = fieldOffset;
79947997 \\}
79957998 , &[_][]const u8{
79967999 "tmp.zig:5:45: error: zero-bit field 'val' in struct 'Empty' has no offset",
......@@ -8004,6 +8007,7 @@ pub fn addCases(ctx: *TestContext) !void {
80048007 \\comptime {
80058008 \\ var foo = Foo {.Baz = {}};
80068009 \\ const bar_val = foo.Bar;
8010 \\ _ = bar_val;
80078011 \\}
80088012 , &[_][]const u8{
80098013 "tmp.zig:7:24: error: accessing union field 'Bar' while field 'Baz' is set",
......@@ -8119,6 +8123,7 @@ pub fn addCases(ctx: *TestContext) !void {
81198123 \\ var x: *const i32 = &w;
81208124 \\ var y: *[1]i32 = x;
81218125 \\ y[0] += 1;
8126 \\ _ = byte;
81228127 \\}
81238128 , &[_][]const u8{
81248129 "tmp.zig:4:22: error: expected type '*[1]i32', found '*const i32'",
......@@ -8145,6 +8150,7 @@ pub fn addCases(ctx: *TestContext) !void {
81458150 \\export fn f2() void {
81468151 \\ var x: anyerror!i32 = error.Bad;
81478152 \\ for ("hello") |_| returns() else unreachable;
8153 \\ _ = x;
81488154 \\}
81498155 , &[_][]const u8{
81508156 "tmp.zig:5:30: error: expression value is ignored",
......@@ -8154,6 +8160,7 @@ pub fn addCases(ctx: *TestContext) !void {
81548160 ctx.objErrStage1("aligned variable of zero-bit type",
81558161 \\export fn f() void {
81568162 \\ var s: struct {} align(4) = undefined;
8163 \\ _ = s;
81578164 \\}
81588165 , &[_][]const u8{
81598166 "tmp.zig:2:5: error: variable 's' of zero-bit type 'struct:2:12' has no in-memory representation, it cannot be aligned",
......@@ -8637,7 +8644,7 @@ pub fn addCases(ctx: *TestContext) !void {
86378644 });
86388645
86398646 ctx.objErrStage1("issue #5221: invalid struct init type referenced by @typeInfo and passed into function",
8640 \\fn ignore(comptime param: anytype) void {}
8647 \\fn ignore(comptime param: anytype) void {_ = param;}
86418648 \\
86428649 \\export fn foo() void {
86438650 \\ const MyStruct = struct {