diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/docs/main.js | 34 | ||||
| -rw-r--r-- | lib/std/Build/Step/ConfigHeader.zig | 4 | ||||
| -rw-r--r-- | lib/std/Build/Step/Run.zig | 2 | ||||
| -rw-r--r-- | lib/std/c/darwin.zig | 86 | ||||
| -rw-r--r-- | lib/std/c/freebsd.zig | 247 | ||||
| -rw-r--r-- | lib/std/c/haiku.zig | 11 | ||||
| -rw-r--r-- | lib/std/c/openbsd.zig | 12 | ||||
| -rw-r--r-- | lib/std/crypto/tls/Client.zig | 2 | ||||
| -rw-r--r-- | lib/std/elf.zig | 7 | ||||
| -rw-r--r-- | lib/std/enums.zig | 16 | ||||
| -rw-r--r-- | lib/std/fmt.zig | 75 | ||||
| -rw-r--r-- | lib/std/fmt/parse_float/parse_float.zig | 8 | ||||
| -rw-r--r-- | lib/std/fs.zig | 3 | ||||
| -rw-r--r-- | lib/std/hash_map.zig | 34 | ||||
| -rw-r--r-- | lib/std/io/reader.zig | 23 | ||||
| -rw-r--r-- | lib/std/math/big/int.zig | 2 | ||||
| -rw-r--r-- | lib/std/math/big/int_test.zig | 26 | ||||
| -rw-r--r-- | lib/std/math/big/rational.zig | 52 | ||||
| -rw-r--r-- | lib/std/meta.zig | 43 | ||||
| -rw-r--r-- | lib/std/net/test.zig | 2 | ||||
| -rw-r--r-- | lib/std/priority_dequeue.zig | 4 | ||||
| -rw-r--r-- | lib/std/target/x86.zig | 6 | ||||
| -rw-r--r-- | lib/std/zig/Ast.zig | 4 | ||||
| -rw-r--r-- | lib/std/zig/number_literal.zig | 10 | ||||
| -rw-r--r-- | lib/std/zig/parser_test.zig | 64 | ||||
| -rw-r--r-- | lib/std/zig/render.zig | 71 |
26 files changed, 632 insertions, 216 deletions
diff --git a/lib/docs/main.js b/lib/docs/main.js index 9b650643e9..f9bb9b9fb8 100644 --- a/lib/docs/main.js +++ b/lib/docs/main.js @@ -1845,18 +1845,19 @@ const NAV_MODES = { let structObj = typeObj; let name = ""; if (opts.wantHtml) { - if (structObj.is_tuple) { - name = "<span class='tok-kw'>tuple</span> { "; - } else { - name = "<span class='tok-kw'>struct</span> { "; - } + name = "<span class='tok-kw'>struct</span>"; } else { - if (structObj.is_tuple) { - name = "tuple { "; + name = "struct"; + } + if (structObj.backing_int !== null) { + if (opts.wantHtml) { + name = "<span class='tok-kw'>packed</span> " + name; } else { - name = "struct { "; + name = "packed " + name; } + name += " (" + exprName(structObj.backing_int, opts) + ")"; } + name += " { "; if (structObj.field_types.length > 1 && opts.wantHtml) { name += "</br>"; } let indent = ""; if (structObj.field_types.length > 1 && opts.wantHtml) { @@ -1982,11 +1983,11 @@ const NAV_MODES = { name += " (" + exprName(unionObj.tag, opts) + ")"; } name += " { "; - if (unionObj.fields.length > 1 && opts.wantHtml) { + if (unionObj.field_types.length > 1 && opts.wantHtml) { name += "</br>"; } let indent = ""; - if (unionObj.fields.length > 1 && opts.wantHtml) { + if (unionObj.field_types.length > 1 && opts.wantHtml) { indent = " " } if (opts.indent) { @@ -1994,17 +1995,17 @@ const NAV_MODES = { } let unionNode = getAstNode(unionObj.src); let field_end = ","; - if (unionObj.fields.length > 1 && opts.wantHtml) { + if (unionObj.field_types.length > 1 && opts.wantHtml) { field_end += "</br>"; } else { field_end += " "; } - for (let i = 0; i < unionObj.fields.length; i += 1) { + for (let i = 0; i < unionObj.field_types.length; i += 1) { let fieldNode = getAstNode(unionNode.fields[i]); let fieldName = fieldNode.name; let html = indent + escapeHtml(fieldName); - let fieldTypeExpr = unionObj.fields[i]; + let fieldTypeExpr = unionObj.field_types[i]; html += ": "; html += exprName(fieldTypeExpr, { ...opts, indent: indent }); @@ -4494,9 +4495,10 @@ function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) { pubDecls: ty[4], field_types: ty[5], field_defaults: ty[6], - is_tuple: ty[7], - line_number: ty[8], - parent_container: ty[9], + backing_int: ty[7], + is_tuple: ty[8], + line_number: ty[9], + parent_container: ty[10], }; case 10: // ComptimeExpr case 11: // ComptimeFloat 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), }; } |
