aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/Build/Step/ConfigHeader.zig4
-rw-r--r--lib/std/Build/Step/Run.zig2
-rw-r--r--lib/std/c/darwin.zig86
-rw-r--r--lib/std/c/freebsd.zig247
-rw-r--r--lib/std/c/haiku.zig11
-rw-r--r--lib/std/c/openbsd.zig12
-rw-r--r--lib/std/crypto/tls/Client.zig2
-rw-r--r--lib/std/elf.zig7
-rw-r--r--lib/std/enums.zig16
-rw-r--r--lib/std/fmt.zig75
-rw-r--r--lib/std/fmt/parse_float/parse_float.zig8
-rw-r--r--lib/std/fs.zig3
-rw-r--r--lib/std/hash_map.zig34
-rw-r--r--lib/std/io/reader.zig23
-rw-r--r--lib/std/math/big/int.zig2
-rw-r--r--lib/std/math/big/int_test.zig26
-rw-r--r--lib/std/math/big/rational.zig52
-rw-r--r--lib/std/meta.zig43
-rw-r--r--lib/std/net/test.zig2
-rw-r--r--lib/std/priority_dequeue.zig4
-rw-r--r--lib/std/target/x86.zig6
-rw-r--r--lib/std/zig/Ast.zig4
-rw-r--r--lib/std/zig/number_literal.zig10
-rw-r--r--lib/std/zig/parser_test.zig64
-rw-r--r--lib/std/zig/render.zig71
25 files changed, 614 insertions, 200 deletions
diff --git a/lib/std/Build/Step/ConfigHeader.zig b/lib/std/Build/Step/ConfigHeader.zig
index a17784c96a..f6939e0e38 100644
--- a/lib/std/Build/Step/ConfigHeader.zig
+++ b/lib/std/Build/Step/ConfigHeader.zig
@@ -306,7 +306,9 @@ fn render_cmake(
}
var it = std.mem.tokenize(u8, line[1..], " \t\r");
const cmakedefine = it.next().?;
- if (!std.mem.eql(u8, cmakedefine, "cmakedefine")) {
+ if (!std.mem.eql(u8, cmakedefine, "cmakedefine") and
+ !std.mem.eql(u8, cmakedefine, "cmakedefine01"))
+ {
try output.appendSlice(line);
try output.appendSlice("\n");
continue;
diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig
index c506e23f90..ba2c084e24 100644
--- a/lib/std/Build/Step/Run.zig
+++ b/lib/std/Build/Step/Run.zig
@@ -822,7 +822,7 @@ fn runCommand(
.zig_test => {
const prefix: []const u8 = p: {
if (result.stdio.test_metadata) |tm| {
- if (tm.next_index <= tm.names.len) {
+ if (tm.next_index > 0 and tm.next_index <= tm.names.len) {
const name = tm.testName(tm.next_index - 1);
break :p b.fmt("while executing test '{s}', ", .{name});
}
diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig
index 7879eddc4b..e5ee8a432a 100644
--- a/lib/std/c/darwin.zig
+++ b/lib/std/c/darwin.zig
@@ -3916,3 +3916,89 @@ pub const THREAD_AFFINITY = struct {
/// individual cpus (high performance cpus group and low consumption one), thus the pthread QOS api is more appropriate in this case.
pub extern "c" fn thread_affinity_get(thread: thread_act_t, flavor: thread_policy_flavor_t, info: thread_policy_t, infocnt: [*]mach_msg_type_number_t, default: *boolean_t) kern_return_t;
pub extern "c" fn thread_affinity_set(thread: thread_act_t, flavor: thread_policy_flavor_t, info: thread_policy_t, infocnt: mach_msg_type_number_t) kern_return_t;
+
+pub const cpu_type_t = integer_t;
+pub const cpu_subtype_t = integer_t;
+pub const cpu_threadtype_t = integer_t;
+pub const host_flavor_t = integer_t;
+pub const host_info_t = *integer_t;
+pub const host_can_has_debugger_info = extern struct {
+ can_has_debugger: boolean_t,
+};
+pub const host_can_has_debugger_info_data_t = host_can_has_debugger_info;
+pub const host_can_has_debugger_info_t = *host_can_has_debugger_info;
+
+pub const host_sched_info = extern struct {
+ min_timeout: integer_t,
+ min_quantum: integer_t,
+};
+pub const host_sched_info_data_t = host_sched_info;
+pub const host_sched_info_t = *host_sched_info;
+
+pub const kernel_resource_sizes = extern struct {
+ task: natural_t,
+ thread: natural_t,
+ port: natural_t,
+ memory_region: natural_t,
+ memory_object: natural_t,
+};
+
+pub const kernel_resource_sizes_data_t = kernel_resource_sizes;
+pub const kernel_resource_sizes_t = *kernel_resource_sizes;
+
+pub const host_priority_info = extern struct {
+ kernel_priority: integer_t,
+ system_priority: integer_t,
+ server_priority: integer_t,
+ user_priority: integer_t,
+ depress_priority: integer_t,
+ idle_priority: integer_t,
+ minimum_priority: integer_t,
+ maximum_priority: integer_t,
+};
+
+pub const host_priority_info_data_t = host_priority_info;
+pub const host_priority_info_t = *host_priority_info;
+
+pub const CPU_STATE_MAX = 4;
+
+pub const host_cpu_load_info = extern struct {
+ cpu_ticks: [CPU_STATE_MAX]natural_t,
+};
+
+pub const host_cpu_load_info_data_t = host_cpu_load_info;
+pub const host_cpu_load_info_t = *host_cpu_load_info;
+
+pub const HOST = struct {
+ pub const BASIC_INFO = 1;
+ pub const SCHED_INFO = 3;
+ pub const RESOURCE_SIZES = 4;
+ pub const PRIORITY_INFO = 5;
+ pub const SEMAPHORE_TRAPS = 7;
+ pub const MACH_MSG_TRAPS = 8;
+ pub const VM_PURGEABLE = 9;
+ pub const DEBUG_INFO_INTERNAL = 10;
+ pub const CAN_HAS_DEBUGGER = 11;
+ pub const PREFERRED_USER_ARCH = 12;
+ pub const CAN_HAS_DEBUGGER_COUNT = @intCast(mach_msg_type_number_t, @sizeOf(host_can_has_debugger_info_data_t) / @sizeOf(integer_t));
+ pub const SCHED_INFO_COUNT = @intCast(mach_msg_type_number_t, @sizeOf(host_sched_info_data_t) / @sizeOf(integer_t));
+ pub const RESOURCES_SIZES_COUNT = @intCast(mach_msg_type_number_t, @sizeOf(kernel_resource_sizes_data_t) / @sizeOf(integer_t));
+ pub const PRIORITY_INFO_COUNT = @intCast(mach_msg_type_number_t, @sizeOf(host_priority_info_data_t) / @sizeOf(integer_t));
+ pub const CPU_LOAD_INFO_COUNT = @intCast(mach_msg_type_number_t, @sizeOf(host_cpu_load_info_data_t) / @sizeOf(integer_t));
+};
+
+pub const host_basic_info = packed struct(u32) {
+ max_cpus: integer_t,
+ avail_cpus: integer_t,
+ memory_size: natural_t,
+ cpu_type: cpu_type_t,
+ cpu_subtype: cpu_subtype_t,
+ cpu_threadtype: cpu_threadtype_t,
+ physical_cpu: integer_t,
+ physical_cpu_max: integer_t,
+ logical_cpu: integer_t,
+ logical_cpu_max: integer_t,
+ max_mem: u64,
+};
+
+pub extern "c" fn host_info(host: host_t, flavor: host_flavor_t, info_out: host_info_t, info_outCnt: [*]mach_msg_type_number_t) kern_return_t;
diff --git a/lib/std/c/freebsd.zig b/lib/std/c/freebsd.zig
index 352c12c695..3b93ccc0c0 100644
--- a/lib/std/c/freebsd.zig
+++ b/lib/std/c/freebsd.zig
@@ -10,7 +10,6 @@ pub const cpuset_t = extern struct {
__bits: [(CPU_SETSIZE + (@bitSizeOf(c_long) - 1)) / @bitSizeOf(c_long)]c_long,
};
-// TODO: can eventually serve for the domainset_t's type too.
fn __BIT_COUNT(bits: []const c_long) c_long {
var count: c_long = 0;
for (bits) |b| {
@@ -64,6 +63,9 @@ pub extern "c" fn getpid() pid_t;
pub extern "c" fn kinfo_getfile(pid: pid_t, cntp: *c_int) ?[*]kinfo_file;
pub extern "c" fn kinfo_getvmmap(pid: pid_t, cntp: *c_int) ?[*]kinfo_vmentry;
+pub extern "c" fn kinfo_getproc(pid: pid_t) ?[*]kinfo_proc;
+pub extern "c" fn kinfo_getvmobject(cntp: *c_int) ?[*]kinfo_vmobject;
+pub extern "c" fn kinfo_getswapvmobject(cntp: *c_int) ?[*]kinfo_vmobject;
pub extern "c" fn cpuset_getaffinity(level: cpulevel_t, which: cpuwhich_t, id: id_t, setsize: usize, mask: *cpuset_t) c_int;
pub extern "c" fn cpuset_setaffinity(level: cpulevel_t, which: cpuwhich_t, id: id_t, setsize: usize, mask: *const cpuset_t) c_int;
@@ -676,6 +678,214 @@ comptime {
std.debug.assert(@sizeOf(kinfo_vmentry) == KINFO_VMENTRY_SIZE);
}
+pub const WMESGLEN = 8;
+pub const LOCKNAMELEN = 8;
+pub const TDNAMLEN = 16;
+pub const COMMLEN = 19;
+pub const MAXCOMLEN = 19;
+pub const KI_EMULNAMELEN = 16;
+pub const KI_NGROUPS = 16;
+pub const LOGNAMELEN = 17;
+pub const LOGINCLASSLEN = 17;
+
+pub const KI_NSPARE_INT = 2;
+pub const KI_NSPARE_LONG = 12;
+pub const KI_NSPARE_PTR = 5;
+
+pub const RUSAGE_SELF = 0;
+pub const RUSAGE_CHILDREN = -1;
+pub const RUSAGE_THREAD = 1;
+
+pub const proc = opaque {};
+pub const thread = opaque {};
+pub const vnode = opaque {};
+pub const filedesc = opaque {};
+pub const pwddesc = opaque {};
+pub const vmspace = opaque {};
+pub const pcb = opaque {};
+pub const lwpid_t = i32;
+pub const fixpt_t = u32;
+pub const vm_size_t = usize;
+pub const segsz_t = isize;
+
+pub const itimerval = extern struct {
+ interval: timeval,
+ value: timeval,
+};
+
+pub const pstats = extern struct {
+ cru: rusage,
+ timer: [3]itimerval,
+ prof: extern struct {
+ base: u8,
+ size: c_ulong,
+ off: c_ulong,
+ scale: c_ulong,
+ },
+ start: timeval,
+};
+
+pub const user = extern struct {
+ stats: pstats,
+ kproc: kinfo_proc,
+};
+
+pub const pargs = extern struct {
+ ref: c_uint,
+ length: c_uint,
+ args: [1]u8,
+};
+
+pub const priority = extern struct {
+ class: u8,
+ level: u8,
+ native: u8,
+ user: u8,
+};
+
+pub const rusage = extern struct {
+ utime: timeval,
+ stime: timeval,
+ maxrss: c_long,
+ ixrss: c_long,
+ idrss: c_long,
+ isrss: c_long,
+ minflt: c_long,
+ majflt: c_long,
+ nswap: c_long,
+ inblock: c_long,
+ oublock: c_long,
+ msgsnd: c_long,
+ msgrcv: c_long,
+ nsignals: c_long,
+ nvcsw: c_long,
+ nivcsw: c_long,
+};
+
+pub const kinfo_proc = extern struct {
+ structsize: c_int,
+ layout: c_int,
+ args: *pargs,
+ paddr: *proc,
+ addr: *user,
+ tracep: *vnode,
+ textvp: *vnode,
+ fd: *filedesc,
+ vmspace: *vmspace,
+ wchan: ?*const anyopaque,
+ pid: pid_t,
+ ppid: pid_t,
+ pgid: pid_t,
+ tpgid: pid_t,
+ sid: pid_t,
+ tsid: pid_t,
+ jobc: c_short,
+ spare_short1: c_short,
+ tdev_freebsd11: u32,
+ siglist: sigset_t,
+ sigmask: sigset_t,
+ sigignore: sigset_t,
+ sigcatch: sigset_t,
+ uid: uid_t,
+ ruid: uid_t,
+ svuid: uid_t,
+ rgid: gid_t,
+ svgid: gid_t,
+ ngroups: c_short,
+ spare_short2: c_short,
+ groups: [KI_NGROUPS]gid_t,
+ size: vm_size_t,
+ rssize: segsz_t,
+ swrss: segsz_t,
+ tsize: segsz_t,
+ dsize: segsz_t,
+ ssize: segsz_t,
+ xstat: c_ushort,
+ acflag: c_ushort,
+ pctcpu: fixpt_t,
+ estcpu: c_uint,
+ slptime: c_uint,
+ swtime: c_uint,
+ cow: c_uint,
+ runtime: u64,
+ start: timeval,
+ childtime: timeval,
+ flag: c_long,
+ kiflag: c_long,
+ traceflag: c_int,
+ stat: u8,
+ nice: i8,
+ lock: u8,
+ rqindex: u8,
+ oncpu_old: u8,
+ lastcpu_old: u8,
+ tdname: [TDNAMLEN + 1]u8,
+ wmesg: [WMESGLEN + 1]u8,
+ login: [LOGNAMELEN + 1]u8,
+ lockname: [LOCKNAMELEN + 1]u8,
+ comm: [COMMLEN + 1]u8,
+ emul: [KI_EMULNAMELEN + 1]u8,
+ loginclass: [LOGINCLASSLEN + 1]u8,
+ moretdname: [MAXCOMLEN - TDNAMLEN + 1]u8,
+ sparestrings: [46]u8,
+ spareints: [KI_NSPARE_INT]c_int,
+ tdev: u64,
+ oncpu: c_int,
+ lastcpu: c_int,
+ tracer: c_int,
+ flag2: c_int,
+ fibnum: c_int,
+ cr_flags: c_uint,
+ jid: c_int,
+ numthreads: c_int,
+ tid: lwpid_t,
+ pri: priority,
+ rusage: rusage,
+ rusage_ch: rusage,
+ pcb: *pcb,
+ stack: ?*anyopaque,
+ udata: ?*anyopaque,
+ tdaddr: *thread,
+ pd: *pwddesc,
+ spareptrs: [KI_NSPARE_PTR]?*anyopaque,
+ sparelongs: [KI_NSPARE_LONG]c_long,
+ sflag: c_long,
+ tdflag: c_long,
+};
+
+pub const KINFO_PROC_SIZE = switch (builtin.cpu.arch) {
+ .x86 => 768,
+ .arm => 816,
+ else => 1088,
+};
+
+comptime {
+ assert(@sizeOf(kinfo_proc) == KINFO_PROC_SIZE);
+}
+
+pub const kinfo_vmobject = extern struct {
+ structsize: c_int,
+ tpe: c_int,
+ size: u64,
+ vn_fileid: u64,
+ vn_fsid_freebsd11: u32,
+ ref_count: c_int,
+ shadow_count: c_int,
+ memattr: c_int,
+ resident: u64,
+ active: u64,
+ inactive: u64,
+ type_spec: extern union {
+ _vn_fsid: u64,
+ _backing_obj: u64,
+ },
+ me: u64,
+ _qspare: [6]u64,
+ swapped: u32,
+ _ispare: [7]u32,
+ path: [PATH_MAX]u8,
+};
+
pub const CTL = struct {
pub const KERN = 1;
pub const DEBUG = 5;
@@ -2362,3 +2572,38 @@ pub extern "c" fn mincore(
length: usize,
vec: [*]u8,
) c_int;
+
+pub const MAXMEMDOM = 8;
+pub const domainid_t = u8;
+
+pub const LIST_ENTRY = opaque {};
+
+pub const DOMAINSET = struct {
+ pub const POLICY_INVALID = 0;
+ pub const POLICY_ROUNDROBIN = 1;
+ pub const POLICY_FIRSTOUCH = 2;
+ pub const POLICY_PREFER = 3;
+ pub const POLICY_INTERLEAVE = 4;
+ pub const POLICY_MAX = DOMAINSET.POLICY_INTERLEAVE;
+};
+
+pub const DOMAINSET_SIZE = 256;
+pub const domainset_t = extern struct {
+ __bits: [(DOMAINSET_SIZE + (@sizeOf(domainset) - 1)) / @bitSizeOf(domainset)]domainset,
+};
+
+pub fn DOMAINSET_COUNT(set: domainset_t) c_int {
+ return @intCast(c_int, __BIT_COUNT(set.__bits[0..]));
+}
+
+pub const domainset = extern struct {
+ link: LIST_ENTRY,
+ mask: domainset_t,
+ policy: u16,
+ prefer: domainid_t,
+ cnt: domainid_t,
+ order: [MAXMEMDOM]domainid_t,
+};
+
+pub extern "c" fn cpuset_getdomain(level: cpulevel_t, which: cpuwhich_t, id: id_t, len: usize, domain: *domainset_t, r: *c_int) c_int;
+pub extern "c" fn cpuset_setdomain(level: cpulevel_t, which: cpuwhich_t, id: id_t, len: usize, domain: *const domainset_t, r: c_int) c_int;
diff --git a/lib/std/c/haiku.zig b/lib/std/c/haiku.zig
index 9b693a59c2..b0fcb710af 100644
--- a/lib/std/c/haiku.zig
+++ b/lib/std/c/haiku.zig
@@ -11,9 +11,9 @@ extern "c" fn _errnop() *c_int;
pub const _errno = _errnop;
-pub extern "c" fn find_directory(which: c_int, volume: i32, createIt: bool, path_ptr: [*]u8, length: i32) status_t;
+pub extern "c" fn find_directory(which: directory_which, volume: i32, createIt: bool, path_ptr: [*]u8, length: i32) status_t;
-pub extern "c" fn find_path(codePointer: *const u8, baseDirectory: c_int, subPath: [*:0]const u8, pathBuffer: [*:0]u8, bufferSize: usize) status_t;
+pub extern "c" fn find_path(codePointer: *const u8, baseDirectory: path_base_directory, subPath: [*:0]const u8, pathBuffer: [*:0]u8, bufferSize: usize) status_t;
pub extern "c" fn find_thread(thread_name: ?*anyopaque) i32;
@@ -1024,6 +1024,13 @@ pub const directory_which = enum(c_int) {
_,
};
+// TODO fill out if needed
+pub const path_base_directory = enum(c_int) {
+ B_FIND_PATH_IMAGE_PATH = 1000,
+};
+
+pub const B_APP_IMAGE_SYMBOL = null;
+
pub const cc_t = u8;
pub const speed_t = u8;
pub const tcflag_t = u32;
diff --git a/lib/std/c/openbsd.zig b/lib/std/c/openbsd.zig
index 51c4bcb6dd..3551f50020 100644
--- a/lib/std/c/openbsd.zig
+++ b/lib/std/c/openbsd.zig
@@ -1127,6 +1127,18 @@ pub usingnamespace switch (builtin.cpu.arch) {
sc_cookie: c_long,
};
},
+ .arm64 => struct {
+ pub const ucontext_t = extern struct {
+ __sc_unused: c_int,
+ sc_mask: c_int,
+ sc_sp: c_ulong,
+ sc_lr: c_ulong,
+ sc_elr: c_ulong,
+ sc_spsr: c_ulong,
+ sc_x: [30]c_ulong,
+ sc_cookie: c_long,
+ };
+ },
else => struct {},
};
diff --git a/lib/std/crypto/tls/Client.zig b/lib/std/crypto/tls/Client.zig
index e67fd20925..cd505afa6e 100644
--- a/lib/std/crypto/tls/Client.zig
+++ b/lib/std/crypto/tls/Client.zig
@@ -1233,7 +1233,7 @@ fn finishRead2(c: *Client, first: []const u8, frag1: []const u8, out: usize) usi
c.partial_cleartext_idx = 0;
c.partial_ciphertext_idx = 0;
c.partial_ciphertext_end = @intCast(@TypeOf(c.partial_ciphertext_end), first.len + frag1.len);
- @memcpy(c.partially_read_buffer[0..first.len], first);
+ std.mem.copyForwards(u8, c.partially_read_buffer[0..first.len], first);
@memcpy(c.partially_read_buffer[first.len..][0..frag1.len], frag1);
}
return out;
diff --git a/lib/std/elf.zig b/lib/std/elf.zig
index e2cad5640e..751f82a9ea 100644
--- a/lib/std/elf.zig
+++ b/lib/std/elf.zig
@@ -296,10 +296,14 @@ pub const SHT_GROUP = 17;
pub const SHT_SYMTAB_SHNDX = 18;
/// Start of OS-specific
pub const SHT_LOOS = 0x60000000;
+/// LLVM address-significance table
+pub const SHT_LLVM_ADDRSIG = 0x6fff4c03;
/// End of OS-specific
pub const SHT_HIOS = 0x6fffffff;
/// Start of processor-specific
pub const SHT_LOPROC = 0x70000000;
+/// Unwind information
+pub const SHT_X86_64_UNWIND = 0x70000001;
/// End of processor-specific
pub const SHT_HIPROC = 0x7fffffff;
/// Start of application-specific
@@ -1632,6 +1636,9 @@ pub const SHF_TLS = 0x400;
/// Identifies a section containing compressed data.
pub const SHF_COMPRESSED = 0x800;
+/// Not to be GCed by the linker
+pub const SHF_GNU_RETAIN = 0x200000;
+
/// This section is excluded from the final executable or shared library.
pub const SHF_EXCLUDE = 0x80000000;
diff --git a/lib/std/enums.zig b/lib/std/enums.zig
index 8e67c358b7..f44f8fd89d 100644
--- a/lib/std/enums.zig
+++ b/lib/std/enums.zig
@@ -48,6 +48,22 @@ pub fn values(comptime E: type) []const E {
return comptime valuesFromFields(E, @typeInfo(E).Enum.fields);
}
+/// A safe alternative to @tagName() for non-exhaustive enums that doesn't
+/// panic when `e` has no tagged value.
+/// Returns the tag name for `e` or null if no tag exists.
+pub fn tagName(comptime E: type, e: E) ?[]const u8 {
+ return inline for (@typeInfo(E).Enum.fields) |f| {
+ if (@enumToInt(e) == f.value) break f.name;
+ } else null;
+}
+
+test tagName {
+ const E = enum(u8) { a, b, _ };
+ try testing.expect(tagName(E, .a) != null);
+ try testing.expectEqualStrings("a", tagName(E, .a).?);
+ try testing.expect(tagName(E, @intToEnum(E, 42)) == null);
+}
+
/// Determines the length of a direct-mapped enum array, indexed by
/// @intCast(usize, @enumToInt(enum_value)).
/// If the enum is non-exhaustive, the resulting length will only be enough
diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig
index cf791df1a6..c3ccd75d27 100644
--- a/lib/std/fmt.zig
+++ b/lib/std/fmt.zig
@@ -2244,8 +2244,8 @@ test "struct" {
field: u8,
};
const value = Struct{ .field = 42 };
- try expectFmt("struct: Struct{ .field = 42 }\n", "struct: {}\n", .{value});
- try expectFmt("struct: Struct{ .field = 42 }\n", "struct: {}\n", .{&value});
+ try expectFmt("struct: fmt.test.struct.Struct{ .field = 42 }\n", "struct: {}\n", .{value});
+ try expectFmt("struct: fmt.test.struct.Struct{ .field = 42 }\n", "struct: {}\n", .{&value});
}
{
const Struct = struct {
@@ -2253,8 +2253,24 @@ test "struct" {
b: u1,
};
const value = Struct{ .a = 0, .b = 1 };
- try expectFmt("struct: Struct{ .a = 0, .b = 1 }\n", "struct: {}\n", .{value});
+ try expectFmt("struct: fmt.test.struct.Struct{ .a = 0, .b = 1 }\n", "struct: {}\n", .{value});
}
+
+ const S = struct {
+ a: u32,
+ b: anyerror,
+ };
+
+ const inst = S{
+ .a = 456,
+ .b = error.Unused,
+ };
+
+ try expectFmt("fmt.test.struct.S{ .a = 456, .b = error.Unused }", "{}", .{inst});
+ // Tuples
+ try expectFmt("{ }", "{}", .{.{}});
+ try expectFmt("{ -1 }", "{}", .{.{-1}});
+ try expectFmt("{ -1, 42, 2.5e+04 }", "{}", .{.{ -1, 42, 0.25e5 }});
}
test "enum" {
@@ -2263,13 +2279,26 @@ test "enum" {
Two,
};
const value = Enum.Two;
- try expectFmt("enum: Enum.Two\n", "enum: {}\n", .{value});
- try expectFmt("enum: Enum.Two\n", "enum: {}\n", .{&value});
- try expectFmt("enum: Enum.One\n", "enum: {}\n", .{Enum.One});
- try expectFmt("enum: Enum.Two\n", "enum: {}\n", .{Enum.Two});
+ try expectFmt("enum: fmt.test.enum.Enum.Two\n", "enum: {}\n", .{value});
+ try expectFmt("enum: fmt.test.enum.Enum.Two\n", "enum: {}\n", .{&value});
+ try expectFmt("enum: fmt.test.enum.Enum.One\n", "enum: {}\n", .{Enum.One});
+ try expectFmt("enum: fmt.test.enum.Enum.Two\n", "enum: {}\n", .{Enum.Two});
// test very large enum to verify ct branch quota is large enough
- try expectFmt("enum: os.windows.win32error.Win32Error.INVALID_FUNCTION\n", "enum: {}\n", .{std.os.windows.Win32Error.INVALID_FUNCTION});
+ // TODO: https://github.com/ziglang/zig/issues/15609
+ if (!((builtin.cpu.arch == .wasm32) and builtin.mode == .Debug)) {
+ try expectFmt("enum: os.windows.win32error.Win32Error.INVALID_FUNCTION\n", "enum: {}\n", .{std.os.windows.Win32Error.INVALID_FUNCTION});
+ }
+
+ const E = enum {
+ One,
+ Two,
+ Three,
+ };
+
+ const inst = E.Two;
+
+ try expectFmt("fmt.test.enum.E.Two", "{}", .{inst});
}
test "non-exhaustive enum" {
@@ -2445,24 +2474,6 @@ test "custom" {
try expectFmt("dim: 10.200x2.220\n", "dim: {d}\n", .{value});
}
-test "struct" {
- const S = struct {
- a: u32,
- b: anyerror,
- };
-
- const inst = S{
- .a = 456,
- .b = error.Unused,
- };
-
- try expectFmt("fmt.test.struct.S{ .a = 456, .b = error.Unused }", "{}", .{inst});
- // Tuples
- try expectFmt("{ }", "{}", .{.{}});
- try expectFmt("{ -1 }", "{}", .{.{-1}});
- try expectFmt("{ -1, 42, 2.5e+04 }", "{}", .{.{ -1, 42, 0.25e5 }});
-}
-
test "union" {
const TU = union(enum) {
float: f32,
@@ -2493,18 +2504,6 @@ test "union" {
try std.testing.expect(mem.eql(u8, eu_result[0..18], "fmt.test.union.EU@"));
}
-test "enum" {
- const E = enum {
- One,
- Two,
- Three,
- };
-
- const inst = E.Two;
-
- try expectFmt("fmt.test.enum.E.Two", "{}", .{inst});
-}
-
test "struct.self-referential" {
const S = struct {
const SelfType = @This();
diff --git a/lib/std/fmt/parse_float/parse_float.zig b/lib/std/fmt/parse_float/parse_float.zig
index 6d77346e9b..08d1c55862 100644
--- a/lib/std/fmt/parse_float/parse_float.zig
+++ b/lib/std/fmt/parse_float/parse_float.zig
@@ -12,6 +12,14 @@ pub const ParseFloatError = error{
};
pub fn parseFloat(comptime T: type, s: []const u8) ParseFloatError!T {
+ if (@typeInfo(T) != .Float) {
+ @compileError("Cannot parse a float into a non-floating point type.");
+ }
+
+ if (T == f80) {
+ @compileError("TODO support parsing float to f80");
+ }
+
if (s.len == 0) {
return error.InvalidCharacter;
}
diff --git a/lib/std/fs.zig b/lib/std/fs.zig
index 9f64387bd8..7327a3a913 100644
--- a/lib/std/fs.zig
+++ b/lib/std/fs.zig
@@ -2999,8 +2999,7 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
.haiku => {
// The only possible issue when looking for the self image path is
// when the buffer is too short.
- // TODO replace with proper constants
- if (os.find_path(null, 1000, null, out_buffer.ptr, out_buffer.len) != 0)
+ if (os.find_path(os.B_APP_IMAGE_SYMBOL, os.path_base_directory.B_FIND_IMAGE_PATH, null, out_buffer.ptr, out_buffer.len) != 0)
return error.Overflow;
return mem.sliceTo(out_buffer, 0);
},
diff --git a/lib/std/hash_map.zig b/lib/std/hash_map.zig
index df3446a2c0..91f5682831 100644
--- a/lib/std/hash_map.zig
+++ b/lib/std/hash_map.zig
@@ -1741,6 +1741,22 @@ test "std.hash_map clone" {
try expectEqual(b.get(1).?, 1);
try expectEqual(b.get(2).?, 2);
try expectEqual(b.get(3).?, 3);
+
+ var original = AutoHashMap(i32, i32).init(std.testing.allocator);
+ defer original.deinit();
+
+ var i: u8 = 0;
+ while (i < 10) : (i += 1) {
+ try original.putNoClobber(i, i * 10);
+ }
+
+ var copy = try original.clone();
+ defer copy.deinit();
+
+ i = 0;
+ while (i < 10) : (i += 1) {
+ try testing.expect(copy.get(i).? == i * 10);
+ }
}
test "std.hash_map ensureTotalCapacity with existing elements" {
@@ -2072,24 +2088,6 @@ test "std.hash_map basic hash map usage" {
try testing.expect(map.remove(3) == true);
}
-test "std.hash_map clone" {
- var original = AutoHashMap(i32, i32).init(std.testing.allocator);
- defer original.deinit();
-
- var i: u8 = 0;
- while (i < 10) : (i += 1) {
- try original.putNoClobber(i, i * 10);
- }
-
- var copy = try original.clone();
- defer copy.deinit();
-
- i = 0;
- while (i < 10) : (i += 1) {
- try testing.expect(copy.get(i).? == i * 10);
- }
-}
-
test "std.hash_map getOrPutAdapted" {
const AdaptedContext = struct {
fn eql(self: @This(), adapted_key: []const u8, test_key: u64) bool {
diff --git a/lib/std/io/reader.zig b/lib/std/io/reader.zig
index 65b7a086c5..0b88e6b31a 100644
--- a/lib/std/io/reader.zig
+++ b/lib/std/io/reader.zig
@@ -553,10 +553,18 @@ test "Reader.readUntilDelimiter returns StreamTooLong, then bytes read until the
}
test "Reader.readUntilDelimiter returns EndOfStream" {
- var buf: [5]u8 = undefined;
- var fis = std.io.fixedBufferStream("");
- const reader = fis.reader();
- try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
+ {
+ var buf: [5]u8 = undefined;
+ var fis = std.io.fixedBufferStream("");
+ const reader = fis.reader();
+ try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
+ }
+ {
+ var buf: [5]u8 = undefined;
+ var fis = std.io.fixedBufferStream("1234");
+ const reader = fis.reader();
+ try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
+ }
}
test "Reader.readUntilDelimiter returns bytes read until delimiter, then EndOfStream" {
@@ -567,13 +575,6 @@ test "Reader.readUntilDelimiter returns bytes read until delimiter, then EndOfSt
try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
}
-test "Reader.readUntilDelimiter returns EndOfStream" {
- var buf: [5]u8 = undefined;
- var fis = std.io.fixedBufferStream("1234");
- const reader = fis.reader();
- try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
-}
-
test "Reader.readUntilDelimiter returns StreamTooLong, then EndOfStream" {
var buf: [5]u8 = undefined;
var fis = std.io.fixedBufferStream("12345");
diff --git a/lib/std/math/big/int.zig b/lib/std/math/big/int.zig
index b01d9b04ff..686a3fdbda 100644
--- a/lib/std/math/big/int.zig
+++ b/lib/std/math/big/int.zig
@@ -1519,7 +1519,7 @@ pub const Mutable = struct {
r.positive = r_positive;
}
- if (xy_trailing != 0) {
+ if (xy_trailing != 0 and r.limbs[r.len - 1] != 0) {
// Manually shift here since we know its limb aligned.
mem.copyBackwards(Limb, r.limbs[xy_trailing..], r.limbs[0..r.len]);
@memset(r.limbs[0..xy_trailing], 0);
diff --git a/lib/std/math/big/int_test.zig b/lib/std/math/big/int_test.zig
index 0066ce9940..0514453cf4 100644
--- a/lib/std/math/big/int_test.zig
+++ b/lib/std/math/big/int_test.zig
@@ -1373,6 +1373,19 @@ test "big.int div trunc single-single -/-" {
try testing.expect((try r.to(i32)) == er);
}
+test "big.int divTrunc #15535" {
+ var one = try Managed.initSet(testing.allocator, 1);
+ defer one.deinit();
+ var x = try Managed.initSet(testing.allocator, std.math.pow(u128, 2, 64));
+ defer x.deinit();
+ var r = try Managed.init(testing.allocator);
+ defer r.deinit();
+ var q = try Managed.init(testing.allocator);
+ defer q.deinit();
+ try q.divTrunc(&r, &x, &x);
+ try testing.expect(r.order(one) == std.math.Order.lt);
+}
+
test "big.int divFloor #10932" {
var a = try Managed.init(testing.allocator);
defer a.deinit();
@@ -2012,15 +2025,10 @@ test "big.int shift-right negative" {
defer arg2.deinit();
try a.shiftRight(&arg2, 10);
try testing.expect((try a.to(i32)) == -1); // -5 >> 10 == -1
-}
-test "big.int shift-right negative" {
- var a = try Managed.init(testing.allocator);
- defer a.deinit();
-
- var arg = try Managed.initSet(testing.allocator, -10);
- defer arg.deinit();
- try a.shiftRight(&arg, 1232);
+ var arg3 = try Managed.initSet(testing.allocator, -10);
+ defer arg3.deinit();
+ try a.shiftRight(&arg3, 1232);
try testing.expect((try a.to(i32)) == -1); // -10 >> 1232 == -1
}
@@ -2483,7 +2491,7 @@ test "big.int gcd non-one small" {
try testing.expect((try r.to(u32)) == 1);
}
-test "big.int gcd non-one small" {
+test "big.int gcd non-one medium" {
var a = try Managed.initSet(testing.allocator, 4864);
defer a.deinit();
var b = try Managed.initSet(testing.allocator, 3458);
diff --git a/lib/std/math/big/rational.zig b/lib/std/math/big/rational.zig
index c3609a6fa2..cdc33e351d 100644
--- a/lib/std/math/big/rational.zig
+++ b/lib/std/math/big/rational.zig
@@ -782,36 +782,38 @@ test "big.rational mul" {
}
test "big.rational div" {
- var a = try Rational.init(testing.allocator);
- defer a.deinit();
- var b = try Rational.init(testing.allocator);
- defer b.deinit();
- var r = try Rational.init(testing.allocator);
- defer r.deinit();
+ {
+ var a = try Rational.init(testing.allocator);
+ defer a.deinit();
+ var b = try Rational.init(testing.allocator);
+ defer b.deinit();
+ var r = try Rational.init(testing.allocator);
+ defer r.deinit();
- try a.setRatio(78923, 23341);
- try b.setRatio(123097, 12441414);
- try a.div(a, b);
+ try a.setRatio(78923, 23341);
+ try b.setRatio(123097, 12441414);
+ try a.div(a, b);
- try r.setRatio(75531824394, 221015929);
- try testing.expect((try a.order(r)) == .eq);
-}
+ try r.setRatio(75531824394, 221015929);
+ try testing.expect((try a.order(r)) == .eq);
+ }
-test "big.rational div" {
- var a = try Rational.init(testing.allocator);
- defer a.deinit();
- var r = try Rational.init(testing.allocator);
- defer r.deinit();
+ {
+ var a = try Rational.init(testing.allocator);
+ defer a.deinit();
+ var r = try Rational.init(testing.allocator);
+ defer r.deinit();
- try a.setRatio(78923, 23341);
- a.invert();
+ try a.setRatio(78923, 23341);
+ a.invert();
- try r.setRatio(23341, 78923);
- try testing.expect((try a.order(r)) == .eq);
+ try r.setRatio(23341, 78923);
+ try testing.expect((try a.order(r)) == .eq);
- try a.setRatio(-78923, 23341);
- a.invert();
+ try a.setRatio(-78923, 23341);
+ a.invert();
- try r.setRatio(-23341, 78923);
- try testing.expect((try a.order(r)) == .eq);
+ try r.setRatio(-23341, 78923);
+ try testing.expect((try a.order(r)) == .eq);
+ }
}
diff --git a/lib/std/meta.zig b/lib/std/meta.zig
index 7be3b71347..cd83061d53 100644
--- a/lib/std/meta.zig
+++ b/lib/std/meta.zig
@@ -14,48 +14,7 @@ test {
_ = TrailerFlags;
}
-pub fn tagName(v: anytype) []const u8 {
- const T = @TypeOf(v);
- switch (@typeInfo(T)) {
- .ErrorSet => return @errorName(v),
- else => return @tagName(v),
- }
-}
-
-test "std.meta.tagName" {
- const E1 = enum {
- A,
- B,
- };
- const E2 = enum(u8) {
- C = 33,
- D,
- };
- const U1 = union(enum) {
- G: u8,
- H: u16,
- };
- const U2 = union(E2) {
- C: u8,
- D: u16,
- };
-
- var u1g = U1{ .G = 0 };
- var u1h = U1{ .H = 0 };
- var u2a = U2{ .C = 0 };
- var u2b = U2{ .D = 0 };
-
- try testing.expect(mem.eql(u8, tagName(E1.A), "A"));
- try testing.expect(mem.eql(u8, tagName(E1.B), "B"));
- try testing.expect(mem.eql(u8, tagName(E2.C), "C"));
- try testing.expect(mem.eql(u8, tagName(E2.D), "D"));
- try testing.expect(mem.eql(u8, tagName(error.E), "E"));
- try testing.expect(mem.eql(u8, tagName(error.F), "F"));
- try testing.expect(mem.eql(u8, tagName(u1g), "G"));
- try testing.expect(mem.eql(u8, tagName(u1h), "H"));
- try testing.expect(mem.eql(u8, tagName(u2a), "C"));
- try testing.expect(mem.eql(u8, tagName(u2b), "D"));
-}
+pub const tagName = @compileError("deprecated; use @tagName or @errorName directly");
/// Given an enum or tagged union, returns true if the comptime-supplied
/// string matches the name of the tag value. This match process should
diff --git a/lib/std/net/test.zig b/lib/std/net/test.zig
index 9923e4932b..817d6c2593 100644
--- a/lib/std/net/test.zig
+++ b/lib/std/net/test.zig
@@ -182,7 +182,7 @@ test "listen on a port, send bytes, receive bytes" {
try testing.expectEqualSlices(u8, "Hello world!", buf[0..n]);
}
-test "listen on a port, send bytes, receive bytes" {
+test "listen on a port, send bytes, receive bytes, async-only" {
if (!std.io.is_async) return error.SkipZigTest;
if (builtin.os.tag != .linux and !builtin.os.tag.isDarwin()) {
diff --git a/lib/std/priority_dequeue.zig b/lib/std/priority_dequeue.zig
index db55be3804..05e3d7e58b 100644
--- a/lib/std/priority_dequeue.zig
+++ b/lib/std/priority_dequeue.zig
@@ -633,7 +633,7 @@ test "std.PriorityDequeue: peekMax" {
try expect(queue.peekMax().? == 9);
}
-test "std.PriorityDequeue: sift up with odd indices" {
+test "std.PriorityDequeue: sift up with odd indices, removeMin" {
var queue = PDQ.init(testing.allocator, {});
defer queue.deinit();
const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
@@ -647,7 +647,7 @@ test "std.PriorityDequeue: sift up with odd indices" {
}
}
-test "std.PriorityDequeue: sift up with odd indices" {
+test "std.PriorityDequeue: sift up with odd indices, removeMax" {
var queue = PDQ.init(testing.allocator, {});
defer queue.deinit();
const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
diff --git a/lib/std/target/x86.zig b/lib/std/target/x86.zig
index c46367e755..bf3b8cb953 100644
--- a/lib/std/target/x86.zig
+++ b/lib/std/target/x86.zig
@@ -326,7 +326,7 @@ pub const all_features = blk: {
};
result[@enumToInt(Feature.avx512ifma)] = .{
.llvm_name = "avx512ifma",
- .description = "Enable AVX-512 Integer Fused Multiple-Add",
+ .description = "Enable AVX-512 Integer Fused Multiply-Add",
.dependencies = featureSet(&[_]Feature{
.avx512f,
}),
@@ -599,14 +599,14 @@ pub const all_features = blk: {
};
result[@enumToInt(Feature.fma)] = .{
.llvm_name = "fma",
- .description = "Enable three-operand fused multiple-add",
+ .description = "Enable three-operand fused multiply-add",
.dependencies = featureSet(&[_]Feature{
.avx,
}),
};
result[@enumToInt(Feature.fma4)] = .{
.llvm_name = "fma4",
- .description = "Enable four-operand fused multiple-add",
+ .description = "Enable four-operand fused multiply-add",
.dependencies = featureSet(&[_]Feature{
.avx,
.sse4a,
diff --git a/lib/std/zig/Ast.zig b/lib/std/zig/Ast.zig
index cb86696e13..7bc78c17da 100644
--- a/lib/std/zig/Ast.zig
+++ b/lib/std/zig/Ast.zig
@@ -3511,3 +3511,7 @@ const Token = std.zig.Token;
const Ast = @This();
const Allocator = std.mem.Allocator;
const Parse = @import("Parse.zig");
+
+test {
+ testing.refAllDecls(@This());
+}
diff --git a/lib/std/zig/number_literal.zig b/lib/std/zig/number_literal.zig
index 1b41908371..b021190ad9 100644
--- a/lib/std/zig/number_literal.zig
+++ b/lib/std/zig/number_literal.zig
@@ -44,8 +44,6 @@ pub const Error = union(enum) {
duplicate_period,
/// Float literal has multiple exponents.
duplicate_exponent: usize,
- /// Decimal float has hexadecimal exponent.
- invalid_hex_exponent: usize,
/// Exponent comes directly after '_' digit separator.
exponent_after_underscore: usize,
/// Special character (+-.) comes directly after exponent.
@@ -103,7 +101,6 @@ pub fn parseNumberLiteral(bytes: []const u8) Result {
},
'e', 'E' => if (base == 10) {
float = true;
- if (base != 10 and base != 16) return .{ .failure = .{ .invalid_float_base = 2 } };
if (exponent) return .{ .failure = .{ .duplicate_exponent = i } };
if (underscore) return .{ .failure = .{ .exponent_after_underscore = i } };
special = c;
@@ -112,10 +109,8 @@ pub fn parseNumberLiteral(bytes: []const u8) Result {
},
'p', 'P' => if (base == 16) {
float = true;
- if (base != 10 and base != 16) return .{ .failure = .{ .invalid_float_base = 2 } };
if (exponent) return .{ .failure = .{ .duplicate_exponent = i } };
if (underscore) return .{ .failure = .{ .exponent_after_underscore = i } };
- if (base != 16) return .{ .failure = .{ .invalid_hex_exponent = i } };
special = c;
exponent = true;
continue;
@@ -123,7 +118,7 @@ pub fn parseNumberLiteral(bytes: []const u8) Result {
'.' => {
float = true;
if (base != 10 and base != 16) return .{ .failure = .{ .invalid_float_base = 2 } };
- if (period) return .{ .failure = .{ .duplicate_exponent = i } };
+ if (period) return .{ .failure = .duplicate_period };
period = true;
if (underscore) return .{ .failure = .{ .special_after_underscore = i } };
special = c;
@@ -131,7 +126,8 @@ pub fn parseNumberLiteral(bytes: []const u8) Result {
},
'+', '-' => {
switch (special) {
- 'p', 'P', 'e', 'E' => {},
+ 'p', 'P' => {},
+ 'e', 'E' => if (base != 10) return .{ .failure = .{ .invalid_exponent_sign = i } },
else => return .{ .failure = .{ .invalid_exponent_sign = i } },
}
special = c;
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index 9176e14480..21785278ec 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -1240,7 +1240,7 @@ test "zig fmt: infix operator and then multiline string literal" {
);
}
-test "zig fmt: infix operator and then multiline string literal" {
+test "zig fmt: infix operator and then multiline string literal over multiple lines" {
try testCanonical(
\\const x = "" ++
\\ \\ hi0
@@ -4310,7 +4310,7 @@ test "zig fmt: comptime before comptime field" {
});
}
-test "zig fmt: invalid else branch statement" {
+test "zig fmt: invalid doc comments on comptime and test blocks" {
try testError(
\\/// This is a doc comment for a comptime block.
\\comptime {}
@@ -5191,7 +5191,7 @@ test "zig fmt: preserve container doc comment in container without trailing comm
);
}
-test "zig fmt: make single-line if no trailing comma" {
+test "zig fmt: make single-line if no trailing comma, fmt: off" {
try testCanonical(
\\// Test trailing comma syntax
\\// zig fmt: off
@@ -5270,7 +5270,7 @@ test "zig fmt: variable initialized with ==" {
, &.{.wrong_equal_var_decl});
}
-test "zig fmt: missing const/var before local variable" {
+test "zig fmt: missing const/var before local variable in comptime block" {
try testError(
\\comptime {
\\ z: u32;
@@ -5732,6 +5732,62 @@ test "zig fmt: canonicalize symbols (asm)" {
);
}
+test "zig fmt: don't canonicalize _ in enums" {
+ try testTransform(
+ \\const A = enum {
+ \\ first,
+ \\ second,
+ \\ third,
+ \\ _,
+ \\};
+ \\const B = enum {
+ \\ @"_",
+ \\ @"__",
+ \\ @"___",
+ \\ @"____",
+ \\};
+ \\const C = struct {
+ \\ @"_": u8,
+ \\ @"__": u8,
+ \\ @"___": u8,
+ \\ @"____": u8,
+ \\};
+ \\const D = union {
+ \\ @"_": u8,
+ \\ @"__": u8,
+ \\ @"___": u8,
+ \\ @"____": u8,
+ \\};
+ \\
+ ,
+ \\const A = enum {
+ \\ first,
+ \\ second,
+ \\ third,
+ \\ _,
+ \\};
+ \\const B = enum {
+ \\ @"_",
+ \\ __,
+ \\ ___,
+ \\ ____,
+ \\};
+ \\const C = struct {
+ \\ _: u8,
+ \\ __: u8,
+ \\ ___: u8,
+ \\ ____: u8,
+ \\};
+ \\const D = union {
+ \\ _: u8,
+ \\ __: u8,
+ \\ ___: u8,
+ \\ ____: u8,
+ \\};
+ \\
+ );
+}
+
test "zig fmt: error for missing sentinel value in sentinel slice" {
try testError(
\\const foo = foo[0..:];
diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig
index 367d06f7c6..e1ccc8e0e8 100644
--- a/lib/std/zig/render.zig
+++ b/lib/std/zig/render.zig
@@ -40,27 +40,28 @@ pub fn renderTree(buffer: *std.ArrayList(u8), tree: Ast) Error!void {
/// Render all members in the given slice, keeping empty lines where appropriate
fn renderMembers(gpa: Allocator, ais: *Ais, tree: Ast, members: []const Ast.Node.Index) Error!void {
if (members.len == 0) return;
- var is_tuple = true;
- for (members) |member| {
- const container_field = tree.fullContainerField(member) orelse continue;
- if (!container_field.ast.tuple_like) {
- is_tuple = false;
- break;
- }
- }
- try renderMember(gpa, ais, tree, members[0], is_tuple, .newline);
+ const container: Container = for (members) |member| {
+ if (tree.fullContainerField(member)) |field| if (!field.ast.tuple_like) break .other;
+ } else .tuple;
+ try renderMember(gpa, ais, tree, container, members[0], .newline);
for (members[1..]) |member| {
try renderExtraNewline(ais, tree, member);
- try renderMember(gpa, ais, tree, member, is_tuple, .newline);
+ try renderMember(gpa, ais, tree, container, member, .newline);
}
}
+const Container = enum {
+ @"enum",
+ tuple,
+ other,
+};
+
fn renderMember(
gpa: Allocator,
ais: *Ais,
tree: Ast,
+ container: Container,
decl: Ast.Node.Index,
- is_tuple: bool,
space: Space,
) Error!void {
const token_tags = tree.tokens.items(.tag);
@@ -180,7 +181,7 @@ fn renderMember(
.container_field_init,
.container_field_align,
.container_field,
- => return renderContainerField(gpa, ais, tree, tree.fullContainerField(decl).?, is_tuple, space),
+ => return renderContainerField(gpa, ais, tree, container, tree.fullContainerField(decl).?, space),
.@"comptime" => return renderExpression(gpa, ais, tree, decl, space),
@@ -1279,19 +1280,23 @@ fn renderContainerField(
gpa: Allocator,
ais: *Ais,
tree: Ast,
+ container: Container,
field_param: Ast.full.ContainerField,
- is_tuple: bool,
space: Space,
) Error!void {
var field = field_param;
- if (!is_tuple) field.convertToNonTupleLike(tree.nodes);
+ if (container != .tuple) field.convertToNonTupleLike(tree.nodes);
+ const quote: QuoteBehavior = switch (container) {
+ .@"enum" => .eagerly_unquote_except_underscore,
+ .tuple, .other => .eagerly_unquote,
+ };
if (field.comptime_token) |t| {
try renderToken(ais, tree, t, .space); // comptime
}
if (field.ast.type_expr == 0 and field.ast.value_expr == 0) {
if (field.ast.align_expr != 0) {
- try renderIdentifier(ais, tree, field.ast.main_token, .space, .eagerly_unquote); // name
+ try renderIdentifier(ais, tree, field.ast.main_token, .space, quote); // name
const lparen_token = tree.firstToken(field.ast.align_expr) - 1;
const align_kw = lparen_token - 1;
const rparen_token = tree.lastToken(field.ast.align_expr) + 1;
@@ -1300,11 +1305,11 @@ fn renderContainerField(
try renderExpression(gpa, ais, tree, field.ast.align_expr, .none); // alignment
return renderToken(ais, tree, rparen_token, .space); // )
}
- return renderIdentifierComma(ais, tree, field.ast.main_token, space, .eagerly_unquote); // name
+ return renderIdentifierComma(ais, tree, field.ast.main_token, space, quote); // name
}
if (field.ast.type_expr != 0 and field.ast.value_expr == 0) {
if (!field.ast.tuple_like) {
- try renderIdentifier(ais, tree, field.ast.main_token, .none, .eagerly_unquote); // name
+ try renderIdentifier(ais, tree, field.ast.main_token, .none, quote); // name
try renderToken(ais, tree, field.ast.main_token + 1, .space); // :
}
@@ -1321,7 +1326,7 @@ fn renderContainerField(
}
}
if (field.ast.type_expr == 0 and field.ast.value_expr != 0) {
- try renderIdentifier(ais, tree, field.ast.main_token, .space, .eagerly_unquote); // name
+ try renderIdentifier(ais, tree, field.ast.main_token, .space, quote); // name
if (field.ast.align_expr != 0) {
const lparen_token = tree.firstToken(field.ast.align_expr) - 1;
const align_kw = lparen_token - 1;
@@ -1335,7 +1340,7 @@ fn renderContainerField(
return renderExpressionComma(gpa, ais, tree, field.ast.value_expr, space); // value
}
if (!field.ast.tuple_like) {
- try renderIdentifier(ais, tree, field.ast.main_token, .none, .eagerly_unquote); // name
+ try renderIdentifier(ais, tree, field.ast.main_token, .none, quote); // name
try renderToken(ais, tree, field.ast.main_token + 1, .space); // :
}
try renderExpression(gpa, ais, tree, field.ast.type_expr, .space); // type
@@ -2054,13 +2059,12 @@ fn renderContainerDecl(
try renderToken(ais, tree, layout_token, .space);
}
- var is_tuple = token_tags[container_decl.ast.main_token] == .keyword_struct;
- if (is_tuple) for (container_decl.ast.members) |member| {
- const container_field = tree.fullContainerField(member) orelse continue;
- if (!container_field.ast.tuple_like) {
- is_tuple = false;
- break;
- }
+ const container: Container = switch (token_tags[container_decl.ast.main_token]) {
+ .keyword_enum => .@"enum",
+ .keyword_struct => for (container_decl.ast.members) |member| {
+ if (tree.fullContainerField(member)) |field| if (!field.ast.tuple_like) break .other;
+ } else .tuple,
+ else => .other,
};
var lbrace: Ast.TokenIndex = undefined;
@@ -2129,7 +2133,7 @@ fn renderContainerDecl(
// Print all the declarations on the same line.
try renderToken(ais, tree, lbrace, .space); // lbrace
for (container_decl.ast.members) |member| {
- try renderMember(gpa, ais, tree, member, is_tuple, .space);
+ try renderMember(gpa, ais, tree, container, member, .space);
}
return renderToken(ais, tree, rbrace, space); // rbrace
}
@@ -2147,9 +2151,9 @@ fn renderContainerDecl(
.container_field_init,
.container_field_align,
.container_field,
- => try renderMember(gpa, ais, tree, member, is_tuple, .comma),
+ => try renderMember(gpa, ais, tree, container, member, .comma),
- else => try renderMember(gpa, ais, tree, member, is_tuple, .newline),
+ else => try renderMember(gpa, ais, tree, container, member, .newline),
}
}
ais.popIndent();
@@ -2565,6 +2569,7 @@ fn renderSpace(ais: *Ais, tree: Ast, token_index: Ast.TokenIndex, lexeme_len: us
const QuoteBehavior = enum {
preserve_when_shadowing,
eagerly_unquote,
+ eagerly_unquote_except_underscore,
};
fn renderIdentifier(ais: *Ais, tree: Ast, token_index: Ast.TokenIndex, space: Space, quote: QuoteBehavior) Error!void {
@@ -2589,7 +2594,9 @@ fn renderIdentifier(ais: *Ais, tree: Ast, token_index: Ast.TokenIndex, space: Sp
// Special case for _ which would incorrectly be rejected by isValidId below.
if (contents.len == 1 and contents[0] == '_') switch (quote) {
.eagerly_unquote => return renderQuotedIdentifier(ais, tree, token_index, space, true),
- .preserve_when_shadowing => return renderQuotedIdentifier(ais, tree, token_index, space, false),
+ .eagerly_unquote_except_underscore,
+ .preserve_when_shadowing,
+ => return renderQuotedIdentifier(ais, tree, token_index, space, false),
};
// Scan the entire name for characters that would (after un-escaping) be illegal in a symbol,
@@ -2653,7 +2660,9 @@ fn renderIdentifier(ais: *Ais, tree: Ast, token_index: Ast.TokenIndex, space: Sp
return renderQuotedIdentifier(ais, tree, token_index, space, false);
}
if (primitives.isPrimitive(buf[0..buf_i])) switch (quote) {
- .eagerly_unquote => return renderQuotedIdentifier(ais, tree, token_index, space, true),
+ .eagerly_unquote,
+ .eagerly_unquote_except_underscore,
+ => return renderQuotedIdentifier(ais, tree, token_index, space, true),
.preserve_when_shadowing => return renderQuotedIdentifier(ais, tree, token_index, space, false),
};
}