mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
parse.zig: make parseParamDeclList check for nonfinal varargs
This commit is contained in:
parent
8bf04c3a69
commit
ff0a15bb7a
@ -297,6 +297,9 @@ pub const Tree = struct {
|
||||
.unattached_doc_comment => {
|
||||
return stream.writeAll("unattached documentation comment");
|
||||
},
|
||||
.varargs_nonfinal => {
|
||||
return stream.writeAll("function prototype has parameter after varargs");
|
||||
},
|
||||
|
||||
.expected_token => {
|
||||
const found_tag = token_tags[parse_error.token];
|
||||
@ -2414,6 +2417,7 @@ pub const Error = struct {
|
||||
invalid_token,
|
||||
same_line_doc_comment,
|
||||
unattached_doc_comment,
|
||||
varargs_nonfinal,
|
||||
|
||||
/// `expected_tag` is populated.
|
||||
expected_token,
|
||||
|
||||
@ -3553,11 +3553,15 @@ const Parser = struct {
|
||||
_ = try p.expectToken(.l_paren);
|
||||
const scratch_top = p.scratch.items.len;
|
||||
defer p.scratch.shrinkRetainingCapacity(scratch_top);
|
||||
var varargs: union(enum){ none, seen, nonfinal: TokenIndex } = .none;
|
||||
while (true) {
|
||||
if (p.eatToken(.r_paren)) |_| break;
|
||||
if (varargs == .seen) varargs = .{ .nonfinal = p.tok_i };
|
||||
const param = try p.expectParamDecl();
|
||||
if (param != 0) {
|
||||
try p.scratch.append(p.gpa, param);
|
||||
} else if (p.token_tags[p.tok_i - 1] == .ellipsis3) {
|
||||
if (varargs == .none) varargs = .seen;
|
||||
}
|
||||
switch (p.token_tags[p.nextToken()]) {
|
||||
.comma => {},
|
||||
@ -3574,6 +3578,9 @@ const Parser = struct {
|
||||
},
|
||||
}
|
||||
}
|
||||
if (varargs == .nonfinal) {
|
||||
try p.warnMsg(.{ .tag = .varargs_nonfinal, .token = varargs.nonfinal });
|
||||
}
|
||||
const params = p.scratch.items[scratch_top..];
|
||||
return switch (params.len) {
|
||||
0 => SmallSpan { .zero_or_one = 0 },
|
||||
|
||||
@ -5171,6 +5171,18 @@ test "recovery: missing while rbrace" {
|
||||
});
|
||||
}
|
||||
|
||||
test "recovery: nonfinal varargs" {
|
||||
try testError(
|
||||
\\extern fn f(a: u32, ..., b: u32) void;
|
||||
\\extern fn g(a: u32, ..., b: anytype) void;
|
||||
\\extern fn h(a: u32, ..., ...) void;
|
||||
, &[_]Error{
|
||||
.varargs_nonfinal,
|
||||
.varargs_nonfinal,
|
||||
.varargs_nonfinal,
|
||||
});
|
||||
}
|
||||
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const print = std.debug.print;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user