mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
update std lib to decls being disallowed between fields
This commit is contained in:
parent
fff00c3bbb
commit
b6fe839248
10 changed files with 103 additions and 42 deletions
|
|
@ -77,7 +77,7 @@ test "encodesTo" {
|
||||||
testing.expectEqual(true, encodesTo("false", "false"));
|
testing.expectEqual(true, encodesTo("false", "false"));
|
||||||
// totally different
|
// totally different
|
||||||
testing.expectEqual(false, encodesTo("false", "true"));
|
testing.expectEqual(false, encodesTo("false", "true"));
|
||||||
// differnt lengths
|
// different lengths
|
||||||
testing.expectEqual(false, encodesTo("false", "other"));
|
testing.expectEqual(false, encodesTo("false", "other"));
|
||||||
// with escape
|
// with escape
|
||||||
testing.expectEqual(true, encodesTo("\\", "\\\\"));
|
testing.expectEqual(true, encodesTo("\\", "\\\\"));
|
||||||
|
|
@ -1771,22 +1771,20 @@ test "parse into struct with misc fields" {
|
||||||
static_array: [3]f64,
|
static_array: [3]f64,
|
||||||
dynamic_array: []f64,
|
dynamic_array: []f64,
|
||||||
|
|
||||||
const Bar = struct {
|
complex: struct {
|
||||||
nested: []const u8,
|
nested: []const u8,
|
||||||
};
|
},
|
||||||
complex: Bar,
|
|
||||||
|
|
||||||
const Baz = struct {
|
veryComplex: []struct {
|
||||||
foo: []const u8,
|
foo: []const u8,
|
||||||
};
|
},
|
||||||
veryComplex: []Baz,
|
|
||||||
|
|
||||||
|
a_union: Union,
|
||||||
const Union = union(enum) {
|
const Union = union(enum) {
|
||||||
x: u8,
|
x: u8,
|
||||||
float: f64,
|
float: f64,
|
||||||
string: []const u8,
|
string: []const u8,
|
||||||
};
|
};
|
||||||
a_union: Union,
|
|
||||||
};
|
};
|
||||||
const r = try parse(T, &TokenStream.init(
|
const r = try parse(T, &TokenStream.init(
|
||||||
\\{
|
\\{
|
||||||
|
|
@ -2323,13 +2321,14 @@ pub const StringifyOptions = struct {
|
||||||
/// How many indentation levels deep are we?
|
/// How many indentation levels deep are we?
|
||||||
indent_level: usize = 0,
|
indent_level: usize = 0,
|
||||||
|
|
||||||
pub const Indentation = union(enum) {
|
/// What character(s) should be used for indentation?
|
||||||
|
indent: union(enum) {
|
||||||
Space: u8,
|
Space: u8,
|
||||||
Tab: void,
|
Tab: void,
|
||||||
};
|
} = .{ .Space = 4 },
|
||||||
|
|
||||||
/// What character(s) should be used for indentation?
|
/// After a colon, should whitespace be inserted?
|
||||||
indent: Indentation = Indentation{ .Space = 4 },
|
separator: bool = true,
|
||||||
|
|
||||||
fn outputIndent(
|
fn outputIndent(
|
||||||
whitespace: @This(),
|
whitespace: @This(),
|
||||||
|
|
@ -2350,17 +2349,17 @@ pub const StringifyOptions = struct {
|
||||||
n_chars *= whitespace.indent_level;
|
n_chars *= whitespace.indent_level;
|
||||||
try out_stream.writeByteNTimes(char, n_chars);
|
try out_stream.writeByteNTimes(char, n_chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// After a colon, should whitespace be inserted?
|
|
||||||
separator: bool = true,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Controls the whitespace emitted
|
/// Controls the whitespace emitted
|
||||||
whitespace: ?Whitespace = null,
|
whitespace: ?Whitespace = null,
|
||||||
|
|
||||||
|
string: StringOptions = StringOptions{ .String = .{} },
|
||||||
|
|
||||||
/// Should []u8 be serialised as a string? or an array?
|
/// Should []u8 be serialised as a string? or an array?
|
||||||
pub const StringOptions = union(enum) {
|
pub const StringOptions = union(enum) {
|
||||||
Array,
|
Array,
|
||||||
|
String: StringOutputOptions,
|
||||||
|
|
||||||
/// String output options
|
/// String output options
|
||||||
const StringOutputOptions = struct {
|
const StringOutputOptions = struct {
|
||||||
|
|
@ -2370,10 +2369,7 @@ pub const StringifyOptions = struct {
|
||||||
/// Should unicode characters be escaped in strings?
|
/// Should unicode characters be escaped in strings?
|
||||||
escape_unicode: bool = false,
|
escape_unicode: bool = false,
|
||||||
};
|
};
|
||||||
String: StringOutputOptions,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
string: StringOptions = StringOptions{ .String = .{} },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fn outputUnicodeEscape(
|
fn outputUnicodeEscape(
|
||||||
|
|
|
||||||
|
|
@ -374,7 +374,7 @@ test "mem.zeroes" {
|
||||||
testing.expect(a.y == 10);
|
testing.expect(a.y == 10);
|
||||||
|
|
||||||
const ZigStruct = struct {
|
const ZigStruct = struct {
|
||||||
const IntegralTypes = struct {
|
integral_types: struct {
|
||||||
integer_0: i0,
|
integer_0: i0,
|
||||||
integer_8: i8,
|
integer_8: i8,
|
||||||
integer_16: i16,
|
integer_16: i16,
|
||||||
|
|
@ -390,16 +390,13 @@ test "mem.zeroes" {
|
||||||
|
|
||||||
float_32: f32,
|
float_32: f32,
|
||||||
float_64: f64,
|
float_64: f64,
|
||||||
};
|
},
|
||||||
|
|
||||||
integral_types: IntegralTypes,
|
pointers: struct {
|
||||||
|
|
||||||
const Pointers = struct {
|
|
||||||
optional: ?*u8,
|
optional: ?*u8,
|
||||||
c_pointer: [*c]u8,
|
c_pointer: [*c]u8,
|
||||||
slice: []u8,
|
slice: []u8,
|
||||||
};
|
},
|
||||||
pointers: Pointers,
|
|
||||||
|
|
||||||
array: [2]u32,
|
array: [2]u32,
|
||||||
optional_int: ?u8,
|
optional_int: ?u8,
|
||||||
|
|
|
||||||
|
|
@ -1226,17 +1226,11 @@ pub const io_cqring_offsets = extern struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const io_uring_sqe = extern struct {
|
pub const io_uring_sqe = extern struct {
|
||||||
opcode: IORING_OP,
|
|
||||||
flags: u8,
|
|
||||||
ioprio: u16,
|
|
||||||
fd: i32,
|
|
||||||
pub const union1 = extern union {
|
pub const union1 = extern union {
|
||||||
off: u64,
|
off: u64,
|
||||||
addr2: u64,
|
addr2: u64,
|
||||||
};
|
};
|
||||||
union1: union1,
|
|
||||||
addr: u64,
|
|
||||||
len: u32,
|
|
||||||
pub const union2 = extern union {
|
pub const union2 = extern union {
|
||||||
rw_flags: kernel_rwf,
|
rw_flags: kernel_rwf,
|
||||||
fsync_flags: u32,
|
fsync_flags: u32,
|
||||||
|
|
@ -1250,8 +1244,7 @@ pub const io_uring_sqe = extern struct {
|
||||||
statx_flags: u32,
|
statx_flags: u32,
|
||||||
fadvise_flags: u32,
|
fadvise_flags: u32,
|
||||||
};
|
};
|
||||||
union2: union2,
|
|
||||||
user_data: u64,
|
|
||||||
pub const union3 = extern union {
|
pub const union3 = extern union {
|
||||||
struct1: extern struct {
|
struct1: extern struct {
|
||||||
/// index into fixed buffers, if used
|
/// index into fixed buffers, if used
|
||||||
|
|
@ -1262,6 +1255,23 @@ pub const io_uring_sqe = extern struct {
|
||||||
},
|
},
|
||||||
__pad2: [3]u64,
|
__pad2: [3]u64,
|
||||||
};
|
};
|
||||||
|
opcode: IORING_OP,
|
||||||
|
flags: u8,
|
||||||
|
ioprio: u16,
|
||||||
|
fd: i32,
|
||||||
|
|
||||||
|
opcode: u8,
|
||||||
|
flags: u8,
|
||||||
|
ioprio: u16,
|
||||||
|
fd: i32,
|
||||||
|
|
||||||
|
union1: union1,
|
||||||
|
addr: u64,
|
||||||
|
len: u32,
|
||||||
|
|
||||||
|
union2: union2,
|
||||||
|
user_data: u64,
|
||||||
|
|
||||||
union3: union3,
|
union3: union3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -384,8 +384,10 @@ pub const EKEYREVOKED = 128;
|
||||||
pub const EKEYREJECTED = 129;
|
pub const EKEYREJECTED = 129;
|
||||||
|
|
||||||
// for robust mutexes
|
// for robust mutexes
|
||||||
|
|
||||||
/// Owner died
|
/// Owner died
|
||||||
pub const EOWNERDEAD = 130;
|
pub const EOWNERDEAD = 130;
|
||||||
|
|
||||||
/// State not recoverable
|
/// State not recoverable
|
||||||
pub const ENOTRECOVERABLE = 131;
|
pub const ENOTRECOVERABLE = 131;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,9 @@ pub const NLM_F_CAPPED = 0x100;
|
||||||
pub const NLM_F_ACK_TLVS = 0x200;
|
pub const NLM_F_ACK_TLVS = 0x200;
|
||||||
|
|
||||||
pub const NetlinkMessageType = extern enum(u16) {
|
pub const NetlinkMessageType = extern enum(u16) {
|
||||||
|
/// < 0x10: reserved control messages
|
||||||
|
pub const MIN_TYPE = 0x10;
|
||||||
|
|
||||||
/// Nothing.
|
/// Nothing.
|
||||||
NOOP = 0x1,
|
NOOP = 0x1,
|
||||||
|
|
||||||
|
|
@ -134,9 +137,6 @@ pub const NetlinkMessageType = extern enum(u16) {
|
||||||
/// Data lost
|
/// Data lost
|
||||||
OVERRUN = 0x4,
|
OVERRUN = 0x4,
|
||||||
|
|
||||||
/// < 0x10: reserved control messages
|
|
||||||
pub const MIN_TYPE = 0x10;
|
|
||||||
|
|
||||||
// rtlink types
|
// rtlink types
|
||||||
|
|
||||||
RTM_NEWLINK = 16,
|
RTM_NEWLINK = 16,
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ const gid_t = std.os.linux.gid_t;
|
||||||
const pid_t = std.os.linux.pid_t;
|
const pid_t = std.os.linux.pid_t;
|
||||||
|
|
||||||
pub const SYS = extern enum(usize) {
|
pub const SYS = extern enum(usize) {
|
||||||
|
pub const arch_specific_syscall = 244;
|
||||||
|
|
||||||
io_setup = 0,
|
io_setup = 0,
|
||||||
io_destroy = 1,
|
io_destroy = 1,
|
||||||
io_submit = 2,
|
io_submit = 2,
|
||||||
|
|
@ -249,7 +251,6 @@ pub const SYS = extern enum(usize) {
|
||||||
accept4 = 242,
|
accept4 = 242,
|
||||||
recvmmsg = 243,
|
recvmmsg = 243,
|
||||||
|
|
||||||
pub const arch_specific_syscall = 244;
|
|
||||||
riscv_flush_icache = arch_specific_syscall + 15,
|
riscv_flush_icache = arch_specific_syscall + 15,
|
||||||
|
|
||||||
wait4 = 260,
|
wait4 = 260,
|
||||||
|
|
|
||||||
|
|
@ -164,6 +164,7 @@ pub const Error = union(enum) {
|
||||||
ExpectedLoopExpr: ExpectedLoopExpr,
|
ExpectedLoopExpr: ExpectedLoopExpr,
|
||||||
ExpectedDerefOrUnwrap: ExpectedDerefOrUnwrap,
|
ExpectedDerefOrUnwrap: ExpectedDerefOrUnwrap,
|
||||||
ExpectedSuffixOp: ExpectedSuffixOp,
|
ExpectedSuffixOp: ExpectedSuffixOp,
|
||||||
|
DeclBetweenFields: DeclBetweenFields,
|
||||||
|
|
||||||
pub fn render(self: *const Error, tokens: *Tree.TokenList, stream: var) !void {
|
pub fn render(self: *const Error, tokens: *Tree.TokenList, stream: var) !void {
|
||||||
switch (self.*) {
|
switch (self.*) {
|
||||||
|
|
@ -211,6 +212,7 @@ pub const Error = union(enum) {
|
||||||
.ExpectedLoopExpr => |*x| return x.render(tokens, stream),
|
.ExpectedLoopExpr => |*x| return x.render(tokens, stream),
|
||||||
.ExpectedDerefOrUnwrap => |*x| return x.render(tokens, stream),
|
.ExpectedDerefOrUnwrap => |*x| return x.render(tokens, stream),
|
||||||
.ExpectedSuffixOp => |*x| return x.render(tokens, stream),
|
.ExpectedSuffixOp => |*x| return x.render(tokens, stream),
|
||||||
|
.DeclBetweenFields => |*x| return x.render(tokens, stream),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -260,6 +262,7 @@ pub const Error = union(enum) {
|
||||||
.ExpectedLoopExpr => |x| return x.token,
|
.ExpectedLoopExpr => |x| return x.token,
|
||||||
.ExpectedDerefOrUnwrap => |x| return x.token,
|
.ExpectedDerefOrUnwrap => |x| return x.token,
|
||||||
.ExpectedSuffixOp => |x| return x.token,
|
.ExpectedSuffixOp => |x| return x.token,
|
||||||
|
.DeclBetweenFields => |x| return x.token,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -304,6 +307,7 @@ pub const Error = union(enum) {
|
||||||
pub const ExtraConstQualifier = SimpleError("Extra const qualifier");
|
pub const ExtraConstQualifier = SimpleError("Extra const qualifier");
|
||||||
pub const ExtraVolatileQualifier = SimpleError("Extra volatile qualifier");
|
pub const ExtraVolatileQualifier = SimpleError("Extra volatile qualifier");
|
||||||
pub const ExtraAllowZeroQualifier = SimpleError("Extra allowzero qualifier");
|
pub const ExtraAllowZeroQualifier = SimpleError("Extra allowzero qualifier");
|
||||||
|
pub const DeclBetweenFields = SimpleError("Declarations are not allowed between container fields");
|
||||||
|
|
||||||
pub const ExpectedCall = struct {
|
pub const ExpectedCall = struct {
|
||||||
node: *Node,
|
node: *Node,
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,18 @@ fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!*Node.Roo
|
||||||
fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !Node.Root.DeclList {
|
fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !Node.Root.DeclList {
|
||||||
var list = Node.Root.DeclList.init(arena);
|
var list = Node.Root.DeclList.init(arena);
|
||||||
|
|
||||||
|
var field_state: union(enum) {
|
||||||
|
/// no fields have been seen
|
||||||
|
none,
|
||||||
|
/// currently parsing fields
|
||||||
|
seen,
|
||||||
|
/// saw fields and then a declaration after them.
|
||||||
|
/// payload is first token of previous declaration.
|
||||||
|
end: TokenIndex,
|
||||||
|
/// ther was a declaration between fields, don't report more errors
|
||||||
|
err,
|
||||||
|
} = .none;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (try parseContainerDocComments(arena, it, tree)) |node| {
|
if (try parseContainerDocComments(arena, it, tree)) |node| {
|
||||||
try list.push(node);
|
try list.push(node);
|
||||||
|
|
@ -97,12 +109,18 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
|
||||||
const doc_comments = try parseDocComment(arena, it, tree);
|
const doc_comments = try parseDocComment(arena, it, tree);
|
||||||
|
|
||||||
if (try parseTestDecl(arena, it, tree)) |node| {
|
if (try parseTestDecl(arena, it, tree)) |node| {
|
||||||
|
if (field_state == .seen) {
|
||||||
|
field_state = .{ .end = node.firstToken() };
|
||||||
|
}
|
||||||
node.cast(Node.TestDecl).?.doc_comments = doc_comments;
|
node.cast(Node.TestDecl).?.doc_comments = doc_comments;
|
||||||
try list.push(node);
|
try list.push(node);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (try parseTopLevelComptime(arena, it, tree)) |node| {
|
if (try parseTopLevelComptime(arena, it, tree)) |node| {
|
||||||
|
if (field_state == .seen) {
|
||||||
|
field_state = .{ .end = node.firstToken() };
|
||||||
|
}
|
||||||
node.cast(Node.Comptime).?.doc_comments = doc_comments;
|
node.cast(Node.Comptime).?.doc_comments = doc_comments;
|
||||||
try list.push(node);
|
try list.push(node);
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -111,6 +129,9 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
|
||||||
const visib_token = eatToken(it, .Keyword_pub);
|
const visib_token = eatToken(it, .Keyword_pub);
|
||||||
|
|
||||||
if (try parseTopLevelDecl(arena, it, tree)) |node| {
|
if (try parseTopLevelDecl(arena, it, tree)) |node| {
|
||||||
|
if (field_state == .seen) {
|
||||||
|
field_state = .{ .end = visib_token orelse node.firstToken() };
|
||||||
|
}
|
||||||
switch (node.id) {
|
switch (node.id) {
|
||||||
.FnProto => {
|
.FnProto => {
|
||||||
node.cast(Node.FnProto).?.doc_comments = doc_comments;
|
node.cast(Node.FnProto).?.doc_comments = doc_comments;
|
||||||
|
|
@ -146,6 +167,18 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
|
||||||
}
|
}
|
||||||
|
|
||||||
if (try parseContainerField(arena, it, tree)) |node| {
|
if (try parseContainerField(arena, it, tree)) |node| {
|
||||||
|
switch (field_state) {
|
||||||
|
.none => field_state = .seen,
|
||||||
|
.err, .seen => {},
|
||||||
|
.end => |tok| {
|
||||||
|
try tree.errors.push(.{
|
||||||
|
.DeclBetweenFields = .{ .token = tok },
|
||||||
|
});
|
||||||
|
// continue parsing, error will be reported later
|
||||||
|
field_state = .err;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
const field = node.cast(Node.ContainerField).?;
|
const field = node.cast(Node.ContainerField).?;
|
||||||
field.doc_comments = doc_comments;
|
field.doc_comments = doc_comments;
|
||||||
try list.push(node);
|
try list.push(node);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,18 @@
|
||||||
|
test "zig fmt: decl between fields" {
|
||||||
|
try testError(
|
||||||
|
\\const S = struct {
|
||||||
|
\\ const foo = 2;
|
||||||
|
\\ const bar = 2;
|
||||||
|
\\ const baz = 2;
|
||||||
|
\\ a: usize,
|
||||||
|
\\ const foo1 = 2;
|
||||||
|
\\ const bar1 = 2;
|
||||||
|
\\ const baz1 = 2;
|
||||||
|
\\ b: usize,
|
||||||
|
\\};
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
test "zig fmt: errdefer with payload" {
|
test "zig fmt: errdefer with payload" {
|
||||||
try testCanonical(
|
try testCanonical(
|
||||||
\\pub fn main() anyerror!void {
|
\\pub fn main() anyerror!void {
|
||||||
|
|
@ -2001,11 +2016,11 @@ test "zig fmt: struct declaration" {
|
||||||
\\ f1: u8,
|
\\ f1: u8,
|
||||||
\\ f3: u8,
|
\\ f3: u8,
|
||||||
\\
|
\\
|
||||||
|
\\ f2: u8,
|
||||||
|
\\
|
||||||
\\ fn method(self: *Self) Self {
|
\\ fn method(self: *Self) Self {
|
||||||
\\ return self.*;
|
\\ return self.*;
|
||||||
\\ }
|
\\ }
|
||||||
\\
|
|
||||||
\\ f2: u8,
|
|
||||||
\\};
|
\\};
|
||||||
\\
|
\\
|
||||||
\\const Ps = packed struct {
|
\\const Ps = packed struct {
|
||||||
|
|
|
||||||
|
|
@ -4,17 +4,20 @@ const std = @import("std");
|
||||||
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||||
cases.add("declaration between fields",
|
cases.add("declaration between fields",
|
||||||
\\const S = struct {
|
\\const S = struct {
|
||||||
\\ a: usize,
|
|
||||||
\\ const foo = 2;
|
\\ const foo = 2;
|
||||||
\\ const bar = 2;
|
\\ const bar = 2;
|
||||||
\\ const baz = 2;
|
\\ const baz = 2;
|
||||||
|
\\ a: usize,
|
||||||
|
\\ const foo1 = 2;
|
||||||
|
\\ const bar1 = 2;
|
||||||
|
\\ const baz1 = 2;
|
||||||
\\ b: usize,
|
\\ b: usize,
|
||||||
\\};
|
\\};
|
||||||
\\comptime {
|
\\comptime {
|
||||||
\\ _ = S;
|
\\ _ = S;
|
||||||
\\}
|
\\}
|
||||||
, &[_][]const u8{
|
, &[_][]const u8{
|
||||||
"tmp.zig:3:5: error: declarations are not allowed between container fields",
|
"tmp.zig:6:5: error: declarations are not allowed between container fields",
|
||||||
});
|
});
|
||||||
|
|
||||||
cases.add("non-extern function with var args",
|
cases.add("non-extern function with var args",
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue