diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/std/array_hash_map.zig | 15 | ||||
| -rw-r--r-- | lib/std/child_process.zig | 2 | ||||
| -rw-r--r-- | lib/std/math.zig | 12 | ||||
| -rw-r--r-- | lib/std/os/wasi.zig | 5 | ||||
| -rw-r--r-- | lib/std/os/windows.zig | 2 | ||||
| -rw-r--r-- | lib/std/zig/Ast.zig | 31 | ||||
| -rw-r--r-- | lib/std/zig/parse.zig | 17 | ||||
| -rw-r--r-- | lib/std/zig/parser_test.zig | 2 | ||||
| -rw-r--r-- | lib/std/zig/render.zig | 21 |
9 files changed, 82 insertions, 25 deletions
diff --git a/lib/std/array_hash_map.zig b/lib/std/array_hash_map.zig index 031a9fab5d..a502c5fa3f 100644 --- a/lib/std/array_hash_map.zig +++ b/lib/std/array_hash_map.zig @@ -773,9 +773,9 @@ pub fn ArrayHashMapUnmanaged( } } + try self.entries.ensureTotalCapacity(allocator, new_capacity); const new_bit_index = try IndexHeader.findBitIndex(new_capacity); const new_header = try IndexHeader.alloc(allocator, new_bit_index); - try self.entries.ensureTotalCapacity(allocator, new_capacity); if (self.index_header) |old_header| old_header.free(allocator); self.insertAllEntriesIntoNewHeader(if (store_hash) {} else ctx, new_header); @@ -2042,6 +2042,19 @@ test "ensure capacity" { try testing.expect(initial_capacity == map.capacity()); } +test "ensure capacity leak" { + try testing.checkAllAllocationFailures(std.testing.allocator, struct { + pub fn f(allocator: Allocator) !void { + var map = AutoArrayHashMap(i32, i32).init(allocator); + defer map.deinit(); + + var i: i32 = 0; + // put more than `linear_scan_max` in so index_header gets allocated. + while (i <= 20) : (i += 1) try map.put(i, i); + } + }.f, .{}); +} + test "big map" { var map = AutoArrayHashMap(i32, i32).init(std.testing.allocator); defer map.deinit(); diff --git a/lib/std/child_process.zig b/lib/std/child_process.zig index f1604bb86c..322c74b11b 100644 --- a/lib/std/child_process.zig +++ b/lib/std/child_process.zig @@ -122,7 +122,7 @@ pub const ChildProcess = struct { } pub fn setUserName(self: *ChildProcess, name: []const u8) !void { - const user_info = try os.getUserInfo(name); + const user_info = try std.process.getUserInfo(name); self.uid = user_info.uid; self.gid = user_info.gid; } diff --git a/lib/std/math.zig b/lib/std/math.zig index a69a6f428c..18c8f555d4 100644 --- a/lib/std/math.zig +++ b/lib/std/math.zig @@ -285,10 +285,10 @@ pub inline fn tan(value: anytype) @TypeOf(value) { return @tan(value); } -// Convert an angle in radians to degrees. T must be a float type. +/// Converts an angle in radians to degrees. T must be a float type. pub fn radiansToDegrees(comptime T: type, angle_in_radians: T) T { - if (@typeInfo(T) != .Float) - @compileError("T must be a float type."); + if (@typeInfo(T) != .Float and @typeInfo(T) != .ComptimeFloat) + @compileError("T must be a float type"); return angle_in_radians * 180.0 / pi; } @@ -300,10 +300,10 @@ test "radiansToDegrees" { try std.testing.expectApproxEqAbs(@as(f32, 360), radiansToDegrees(f32, 2.0 * pi), 1e-6); } -// Convert an angle in degrees to radians. T must be a float type. +/// Converts an angle in degrees to radians. T must be a float type. pub fn degreesToRadians(comptime T: type, angle_in_degrees: T) T { - if (@typeInfo(T) != .Float) - @compileError("T must be a float type."); + if (@typeInfo(T) != .Float and @typeInfo(T) != .ComptimeFloat) + @compileError("T must be a float type"); return angle_in_degrees * pi / 180.0; } diff --git a/lib/std/os/wasi.zig b/lib/std/os/wasi.zig index ec2c577de1..db6b4c930c 100644 --- a/lib/std/os/wasi.zig +++ b/lib/std/os/wasi.zig @@ -76,6 +76,7 @@ pub extern "wasi_snapshot_preview1" fn random_get(buf: [*]u8, buf_len: usize) er pub extern "wasi_snapshot_preview1" fn sched_yield() errno_t; +pub extern "wasi_snapshot_preview1" fn sock_accept(sock: fd_t, flags: fdflags_t, result_fd: *fd_t) errno_t; pub extern "wasi_snapshot_preview1" fn sock_recv(sock: fd_t, ri_data: *const iovec_t, ri_data_len: usize, ri_flags: riflags_t, ro_datalen: *usize, ro_flags: *roflags_t) errno_t; pub extern "wasi_snapshot_preview1" fn sock_send(sock: fd_t, si_data: *const ciovec_t, si_data_len: usize, si_flags: siflags_t, so_datalen: *usize) errno_t; pub extern "wasi_snapshot_preview1" fn sock_shutdown(sock: fd_t, how: sdflags_t) errno_t; @@ -434,6 +435,7 @@ pub const RIGHT = struct { pub const PATH_UNLINK_FILE: rights_t = 0x0000000004000000; pub const POLL_FD_READWRITE: rights_t = 0x0000000008000000; pub const SOCK_SHUTDOWN: rights_t = 0x0000000010000000; + pub const SOCK_ACCEPT: rights_t = 0x0000000020000000; pub const ALL: rights_t = FD_DATASYNC | FD_READ | FD_SEEK | @@ -462,7 +464,8 @@ pub const RIGHT = struct { PATH_REMOVE_DIRECTORY | PATH_UNLINK_FILE | POLL_FD_READWRITE | - SOCK_SHUTDOWN; + SOCK_SHUTDOWN | + SOCK_ACCEPT; }; pub const sdflags_t = u8; diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index c20457943b..f6d148a317 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -3695,4 +3695,4 @@ pub const CTRL_CLOSE_EVENT: DWORD = 2; pub const CTRL_LOGOFF_EVENT: DWORD = 5; pub const CTRL_SHUTDOWN_EVENT: DWORD = 6; -pub const HANDLER_ROUTINE = std.meta.FnPtr(fn (dwCtrlType: DWORD) callconv(.C) BOOL); +pub const HANDLER_ROUTINE = std.meta.FnPtr(fn (dwCtrlType: DWORD) callconv(WINAPI) BOOL); diff --git a/lib/std/zig/Ast.zig b/lib/std/zig/Ast.zig index bfa73dc9ac..62a567387f 100644 --- a/lib/std/zig/Ast.zig +++ b/lib/std/zig/Ast.zig @@ -643,11 +643,23 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { n = datas[n].lhs; } }, + .switch_case_inline_one => { + if (datas[n].lhs == 0) { + return main_tokens[n] - 2 - end_offset; // else token + } else { + return firstToken(tree, datas[n].lhs) - 1; + } + }, .switch_case => { const extra = tree.extraData(datas[n].lhs, Node.SubRange); assert(extra.end - extra.start > 0); n = tree.extra_data[extra.start]; }, + .switch_case_inline => { + const extra = tree.extraData(datas[n].lhs, Node.SubRange); + assert(extra.end - extra.start > 0); + return firstToken(tree, tree.extra_data[extra.start]) - 1; + }, .asm_output, .asm_input => { assert(token_tags[main_tokens[n] - 1] == .l_bracket); @@ -763,7 +775,9 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { .ptr_type_bit_range, .array_type, .switch_case_one, + .switch_case_inline_one, .switch_case, + .switch_case_inline, .switch_range, => n = datas[n].rhs, @@ -1755,7 +1769,7 @@ pub fn switchCaseOne(tree: Ast, node: Node.Index) full.SwitchCase { .values = if (data.lhs == 0) values[0..0] else values[0..1], .arrow_token = tree.nodes.items(.main_token)[node], .target_expr = data.rhs, - }); + }, node); } pub fn switchCase(tree: Ast, node: Node.Index) full.SwitchCase { @@ -1765,7 +1779,7 @@ pub fn switchCase(tree: Ast, node: Node.Index) full.SwitchCase { .values = tree.extra_data[extra.start..extra.end], .arrow_token = tree.nodes.items(.main_token)[node], .target_expr = data.rhs, - }); + }, node); } pub fn asmSimple(tree: Ast, node: Node.Index) full.Asm { @@ -2038,15 +2052,21 @@ fn fullContainerDecl(tree: Ast, info: full.ContainerDecl.Components) full.Contai return result; } -fn fullSwitchCase(tree: Ast, info: full.SwitchCase.Components) full.SwitchCase { +fn fullSwitchCase(tree: Ast, info: full.SwitchCase.Components, node: Node.Index) full.SwitchCase { const token_tags = tree.tokens.items(.tag); + const node_tags = tree.nodes.items(.tag); var result: full.SwitchCase = .{ .ast = info, .payload_token = null, + .inline_token = null, }; if (token_tags[info.arrow_token + 1] == .pipe) { result.payload_token = info.arrow_token + 2; } + switch (node_tags[node]) { + .switch_case_inline, .switch_case_inline_one => result.inline_token = firstToken(tree, node), + else => {}, + } return result; } @@ -2454,6 +2474,7 @@ pub const full = struct { }; pub const SwitchCase = struct { + inline_token: ?TokenIndex, /// Points to the first token after the `|`. Will either be an identifier or /// a `*` (with an identifier immediately after it). payload_token: ?TokenIndex, @@ -2847,9 +2868,13 @@ pub const Node = struct { /// `lhs => rhs`. If lhs is omitted it means `else`. /// main_token is the `=>` switch_case_one, + /// Same ast `switch_case_one` but the case is inline + switch_case_inline_one, /// `a, b, c => rhs`. `SubRange[lhs]`. /// main_token is the `=>` switch_case, + /// Same ast `switch_case` but the case is inline + switch_case_inline, /// `lhs...rhs`. switch_range, /// `while (lhs) rhs`. diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig index 43b6eda8e0..db56cef21e 100644 --- a/lib/std/zig/parse.zig +++ b/lib/std/zig/parse.zig @@ -3100,7 +3100,7 @@ const Parser = struct { return identifier; } - /// SwitchProng <- SwitchCase EQUALRARROW PtrPayload? AssignExpr + /// SwitchProng <- KEYWORD_inline? SwitchCase EQUALRARROW PtrIndexPayload? AssignExpr /// SwitchCase /// <- SwitchItem (COMMA SwitchItem)* COMMA? /// / KEYWORD_else @@ -3108,6 +3108,8 @@ const Parser = struct { const scratch_top = p.scratch.items.len; defer p.scratch.shrinkRetainingCapacity(scratch_top); + const is_inline = p.eatToken(.keyword_inline) != null; + if (p.eatToken(.keyword_else) == null) { while (true) { const item = try p.parseSwitchItem(); @@ -3115,15 +3117,18 @@ const Parser = struct { try p.scratch.append(p.gpa, item); if (p.eatToken(.comma) == null) break; } - if (scratch_top == p.scratch.items.len) return null_node; + if (scratch_top == p.scratch.items.len) { + if (is_inline) p.tok_i -= 1; + return null_node; + } } const arrow_token = try p.expectToken(.equal_angle_bracket_right); - _ = try p.parsePtrPayload(); + _ = try p.parsePtrIndexPayload(); const items = p.scratch.items[scratch_top..]; switch (items.len) { 0 => return p.addNode(.{ - .tag = .switch_case_one, + .tag = if (is_inline) .switch_case_inline_one else .switch_case_one, .main_token = arrow_token, .data = .{ .lhs = 0, @@ -3131,7 +3136,7 @@ const Parser = struct { }, }), 1 => return p.addNode(.{ - .tag = .switch_case_one, + .tag = if (is_inline) .switch_case_inline_one else .switch_case_one, .main_token = arrow_token, .data = .{ .lhs = items[0], @@ -3139,7 +3144,7 @@ const Parser = struct { }, }), else => return p.addNode(.{ - .tag = .switch_case, + .tag = if (is_inline) .switch_case_inline else .switch_case, .main_token = arrow_token, .data = .{ .lhs = try p.addExtra(try p.listToSpan(items)), diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index 0e1817ffab..4e155df6d8 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -3276,6 +3276,8 @@ test "zig fmt: switch" { \\ switch (u) { \\ Union.Int => |int| {}, \\ Union.Float => |*float| unreachable, + \\ 1 => |a, b| unreachable, + \\ 2 => |*a, b| unreachable, \\ } \\} \\ diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index 6ef0cfcd6f..ab009f8390 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -685,8 +685,8 @@ fn renderExpression(gpa: Allocator, ais: *Ais, tree: Ast, node: Ast.Node.Index, return renderToken(ais, tree, tree.lastToken(node), space); // rbrace }, - .switch_case_one => return renderSwitchCase(gpa, ais, tree, tree.switchCaseOne(node), space), - .switch_case => return renderSwitchCase(gpa, ais, tree, tree.switchCase(node), space), + .switch_case_one, .switch_case_inline_one => return renderSwitchCase(gpa, ais, tree, tree.switchCaseOne(node), space), + .switch_case, .switch_case_inline => return renderSwitchCase(gpa, ais, tree, tree.switchCase(node), space), .while_simple => return renderWhile(gpa, ais, tree, tree.whileSimple(node), space), .while_cont => return renderWhile(gpa, ais, tree, tree.whileCont(node), space), @@ -1509,6 +1509,11 @@ fn renderSwitchCase( break :blk hasComment(tree, tree.firstToken(switch_case.ast.values[0]), switch_case.ast.arrow_token); }; + // render inline keyword + if (switch_case.inline_token) |some| { + try renderToken(ais, tree, some, .space); + } + // Render everything before the arrow if (switch_case.ast.values.len == 0) { try renderToken(ais, tree, switch_case.ast.arrow_token - 1, .space); // else keyword @@ -1536,13 +1541,17 @@ fn renderSwitchCase( if (switch_case.payload_token) |payload_token| { try renderToken(ais, tree, payload_token - 1, .none); // pipe + const ident = payload_token + @boolToInt(token_tags[payload_token] == .asterisk); if (token_tags[payload_token] == .asterisk) { try renderToken(ais, tree, payload_token, .none); // asterisk - try renderToken(ais, tree, payload_token + 1, .none); // identifier - try renderToken(ais, tree, payload_token + 2, pre_target_space); // pipe + } + try renderToken(ais, tree, ident, .none); // identifier + if (token_tags[ident + 1] == .comma) { + try renderToken(ais, tree, ident + 1, .space); // , + try renderToken(ais, tree, ident + 2, .none); // identifier + try renderToken(ais, tree, ident + 3, pre_target_space); // pipe } else { - try renderToken(ais, tree, payload_token, .none); // identifier - try renderToken(ais, tree, payload_token + 1, pre_target_space); // pipe + try renderToken(ais, tree, ident + 1, pre_target_space); // pipe } } |
