Merge remote-tracking branch 'origin/master' into stage2-whole-file-astgen

In particular I wanted the change that makes `suspend;` illegal in the
parser.
This commit is contained in:
Andrew Kelley
2021-04-24 10:44:41 -07:00
73 changed files with 1160 additions and 468 deletions

View File

@@ -852,7 +852,7 @@ const Parser = struct {
/// <- KEYWORD_comptime? VarDecl
/// / KEYWORD_comptime BlockExprStatement
/// / KEYWORD_nosuspend BlockExprStatement
/// / KEYWORD_suspend (SEMICOLON / BlockExprStatement)
/// / KEYWORD_suspend BlockExprStatement
/// / KEYWORD_defer BlockExprStatement
/// / KEYWORD_errdefer Payload? BlockExprStatement
/// / IfStatement
@@ -892,6 +892,7 @@ const Parser = struct {
},
.keyword_suspend => {
const token = p.nextToken();
// TODO remove this special case when 0.9.0 is released.
const block_expr: Node.Index = if (p.eatToken(.semicolon) != null)
0
else

View File

@@ -40,6 +40,21 @@ test "zig fmt: rewrite inline functions as callconv(.Inline)" {
);
}
// TODO Remove this after zig 0.9.0 is released.
test "zig fmt: rewrite suspend without block expression" {
try testTransform(
\\fn foo() void {
\\ suspend;
\\}
\\
,
\\fn foo() void {
\\ suspend {}
\\}
\\
);
}
test "zig fmt: simple top level comptime block" {
try testCanonical(
\\// line comment
@@ -1315,6 +1330,27 @@ test "zig fmt: 'zig fmt: (off|on)' works in the middle of code" {
);
}
test "zig fmt: 'zig fmt: on' indentation is unchanged" {
try testCanonical(
\\fn initOptionsAndLayouts(output: *Output, context: *Context) !void {
\\ // zig fmt: off
\\ try output.main_amount.init(output, "main_amount"); errdefer optput.main_amount.deinit();
\\ try output.main_factor.init(output, "main_factor"); errdefer optput.main_factor.deinit();
\\ try output.view_padding.init(output, "view_padding"); errdefer optput.view_padding.deinit();
\\ try output.outer_padding.init(output, "outer_padding"); errdefer optput.outer_padding.deinit();
\\ // zig fmt: on
\\
\\ // zig fmt: off
\\ try output.top.init(output, .top); errdefer optput.top.deinit();
\\ try output.right.init(output, .right); errdefer optput.right.deinit();
\\ try output.bottom.init(output, .bottom); errdefer optput.bottom.deinit();
\\ try output.left.init(output, .left); errdefer optput.left.deinit();
\\ // zig fmt: on
\\}
\\
);
}
test "zig fmt: pointer of unknown length" {
try testCanonical(
\\fn foo(ptr: [*]u8) void {}
@@ -3644,9 +3680,9 @@ test "zig fmt: async functions" {
\\fn simpleAsyncFn() void {
\\ const a = async a.b();
\\ x += 1;
\\ suspend;
\\ suspend {}
\\ x += 1;
\\ suspend;
\\ suspend {}
\\ const p: anyframe->void = async simpleAsyncFn() catch unreachable;
\\ await p;
\\}
@@ -5001,6 +5037,21 @@ test "recovery: invalid comptime" {
});
}
test "recovery: missing block after suspend" {
// TODO Enable this after zig 0.9.0 is released.
if (true) return error.SkipZigTest;
try testError(
\\fn foo() void {
\\ suspend;
\\ nosuspend;
\\}
, &[_]Error{
.expected_block_or_expr,
.expected_block_or_expr,
});
}
test "recovery: missing block after for/while loops" {
try testError(
\\test "" { while (foo) }
@@ -5144,7 +5195,7 @@ fn testError(source: []const u8, expected_errors: []const Error) !void {
var tree = try std.zig.parse(std.testing.allocator, source);
defer tree.deinit(std.testing.allocator);
std.testing.expect(tree.errors.len == expected_errors.len);
std.testing.expectEqual(expected_errors.len, tree.errors.len);
for (expected_errors) |expected, i| {
std.testing.expectEqual(expected, tree.errors[i].tag);
}

View File

@@ -269,7 +269,12 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
try renderToken(ais, tree, suspend_token, .space);
return renderExpression(gpa, ais, tree, body, space);
} else {
return renderToken(ais, tree, suspend_token, space);
// TODO remove this special case when 0.9.0 is released.
assert(space == .semicolon);
try renderToken(ais, tree, suspend_token, .space);
try ais.writer().writeAll("{}");
try ais.insertNewline();
return;
}
},
@@ -2310,9 +2315,9 @@ fn renderComments(ais: *Ais, tree: ast.Tree, start: usize, end: usize) Error!boo
// to the underlying writer, fixing up invaild whitespace.
const disabled_source = tree.source[ais.disabled_offset.?..comment_start];
try writeFixingWhitespace(ais.underlying_writer, disabled_source);
ais.disabled_offset = null;
// Write with the canonical single space.
try ais.writer().writeAll("// zig fmt: on\n");
try ais.underlying_writer.writeAll("// zig fmt: on\n");
ais.disabled_offset = null;
} else if (ais.disabled_offset == null and mem.eql(u8, comment_content, "zig fmt: off")) {
// Write with the canonical single space.
try ais.writer().writeAll("// zig fmt: off\n");