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 => {
|
.unattached_doc_comment => {
|
||||||
return stream.writeAll("unattached documentation comment");
|
return stream.writeAll("unattached documentation comment");
|
||||||
},
|
},
|
||||||
|
.varargs_nonfinal => {
|
||||||
|
return stream.writeAll("function prototype has parameter after varargs");
|
||||||
|
},
|
||||||
|
|
||||||
.expected_token => {
|
.expected_token => {
|
||||||
const found_tag = token_tags[parse_error.token];
|
const found_tag = token_tags[parse_error.token];
|
||||||
@ -2414,6 +2417,7 @@ pub const Error = struct {
|
|||||||
invalid_token,
|
invalid_token,
|
||||||
same_line_doc_comment,
|
same_line_doc_comment,
|
||||||
unattached_doc_comment,
|
unattached_doc_comment,
|
||||||
|
varargs_nonfinal,
|
||||||
|
|
||||||
/// `expected_tag` is populated.
|
/// `expected_tag` is populated.
|
||||||
expected_token,
|
expected_token,
|
||||||
|
|||||||
@ -3553,11 +3553,15 @@ const Parser = struct {
|
|||||||
_ = try p.expectToken(.l_paren);
|
_ = try p.expectToken(.l_paren);
|
||||||
const scratch_top = p.scratch.items.len;
|
const scratch_top = p.scratch.items.len;
|
||||||
defer p.scratch.shrinkRetainingCapacity(scratch_top);
|
defer p.scratch.shrinkRetainingCapacity(scratch_top);
|
||||||
|
var varargs: union(enum){ none, seen, nonfinal: TokenIndex } = .none;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (p.eatToken(.r_paren)) |_| break;
|
if (p.eatToken(.r_paren)) |_| break;
|
||||||
|
if (varargs == .seen) varargs = .{ .nonfinal = p.tok_i };
|
||||||
const param = try p.expectParamDecl();
|
const param = try p.expectParamDecl();
|
||||||
if (param != 0) {
|
if (param != 0) {
|
||||||
try p.scratch.append(p.gpa, param);
|
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()]) {
|
switch (p.token_tags[p.nextToken()]) {
|
||||||
.comma => {},
|
.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..];
|
const params = p.scratch.items[scratch_top..];
|
||||||
return switch (params.len) {
|
return switch (params.len) {
|
||||||
0 => SmallSpan { .zero_or_one = 0 },
|
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 std = @import("std");
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
const print = std.debug.print;
|
const print = std.debug.print;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user