| author | |
| committer | |
| log | 5ec0a7d8a5201fb35334ce62f82c5958b6ba296e |
| tree | 1874ea546d4b71e1c02f3cd37e7b2747f3f791e6 |
| parent | 9b74651cd2b799a73518de26c8293636f910c833 |
8 files changed, 72 insertions(+), 116 deletions(-)
lib/std/Io/Writer.zig+21-15| ... | ... | @@ -1370,19 +1370,12 @@ pub fn printValue( |
| 1370 | 1370 | }, |
| 1371 | 1371 | .array => { |
| 1372 | 1372 | if (!is_any) @compileError("cannot format array without a specifier (i.e. {s} or {any})"); |
| 1373 | if (max_depth == 0) return w.writeAll("{ ... }"); | |
| 1374 | try w.writeAll("{ "); | |
| 1375 | for (value, 0..) |elem, i| { | |
| 1376 | try w.printValue(fmt, options, elem, max_depth - 1); | |
| 1377 | if (i < value.len - 1) { | |
| 1378 | try w.writeAll(", "); | |
| 1379 | } | |
| 1380 | } | |
| 1381 | try w.writeAll(" }"); | |
| 1373 | return printArray(w, fmt, options, &value, max_depth); | |
| 1382 | 1374 | }, |
| 1383 | .vector => { | |
| 1375 | .vector => |vector| { | |
| 1384 | 1376 | if (!is_any and fmt.len != 0) invalidFmtError(fmt, value); |
| 1385 | return printVector(w, fmt, options, value, max_depth); | |
| 1377 | const array: [vector.len]vector.child = value; | |
| 1378 | return printArray(w, fmt, options, &array, max_depth); | |
| 1386 | 1379 | }, |
| 1387 | 1380 | .@"fn" => @compileError("unable to format function body type, use '*const " ++ @typeName(T) ++ "' for a function pointer type"), |
| 1388 | 1381 | .type => { |
| ... | ... | @@ -1436,12 +1429,25 @@ pub fn printVector( |
| 1436 | 1429 | value: anytype, |
| 1437 | 1430 | max_depth: usize, |
| 1438 | 1431 | ) Error!void { |
| 1439 | const len = @typeInfo(@TypeOf(value)).vector.len; | |
| 1432 | const vector = @typeInfo(@TypeOf(value)).vector; | |
| 1433 | const array: [vector.len]vector.child = value; | |
| 1434 | return printArray(w, fmt, options, &array, max_depth); | |
| 1435 | } | |
| 1436 | ||
| 1437 | pub fn printArray( | |
| 1438 | w: *Writer, | |
| 1439 | comptime fmt: []const u8, | |
| 1440 | options: std.fmt.Options, | |
| 1441 | ptr_to_array: anytype, | |
| 1442 | max_depth: usize, | |
| 1443 | ) Error!void { | |
| 1440 | 1444 | if (max_depth == 0) return w.writeAll("{ ... }"); |
| 1441 | 1445 | try w.writeAll("{ "); |
| 1442 | inline for (0..len) |i| { | |
| 1443 | try w.printValue(fmt, options, value[i], max_depth - 1); | |
| 1444 | if (i < len - 1) try w.writeAll(", "); | |
| 1446 | for (ptr_to_array, 0..) |elem, i| { | |
| 1447 | try w.printValue(fmt, options, elem, max_depth - 1); | |
| 1448 | if (i < ptr_to_array.len - 1) { | |
| 1449 | try w.writeAll(", "); | |
| 1450 | } | |
| 1445 | 1451 | } |
| 1446 | 1452 | try w.writeAll(" }"); |
| 1447 | 1453 | } |
lib/std/crypto/chacha20.zig+10-10| ... | ... | @@ -215,7 +215,7 @@ fn ChaChaVecImpl(comptime rounds_nb: usize, comptime degree: comptime_int) type |
| 215 | 215 | } |
| 216 | 216 | } |
| 217 | 217 | |
| 218 | fn hashToBytes(comptime dm: usize, out: *[64 * dm]u8, x: BlockVec) void { | |
| 218 | fn hashToBytes(comptime dm: usize, out: *[64 * dm]u8, x: *const BlockVec) void { | |
| 219 | 219 | inline for (0..dm) |d| { |
| 220 | 220 | for (0..4) |i| { |
| 221 | 221 | mem.writeInt(u32, out[64 * d + 16 * i + 0 ..][0..4], x[i][0 + 4 * d], .little); |
| ... | ... | @@ -242,7 +242,7 @@ fn ChaChaVecImpl(comptime rounds_nb: usize, comptime degree: comptime_int) type |
| 242 | 242 | while (degree >= d and i + 64 * d <= in.len) : (i += 64 * d) { |
| 243 | 243 | chacha20Core(x[0..], ctx); |
| 244 | 244 | contextFeedback(&x, ctx); |
| 245 | hashToBytes(d, buf[0 .. 64 * d], x); | |
| 245 | hashToBytes(d, buf[0 .. 64 * d], &x); | |
| 246 | 246 | |
| 247 | 247 | var xout = out[i..]; |
| 248 | 248 | const xin = in[i..]; |
| ... | ... | @@ -266,7 +266,7 @@ fn ChaChaVecImpl(comptime rounds_nb: usize, comptime degree: comptime_int) type |
| 266 | 266 | if (i < in.len) { |
| 267 | 267 | chacha20Core(x[0..], ctx); |
| 268 | 268 | contextFeedback(&x, ctx); |
| 269 | hashToBytes(1, buf[0..64], x); | |
| 269 | hashToBytes(1, buf[0..64], &x); | |
| 270 | 270 | |
| 271 | 271 | var xout = out[i..]; |
| 272 | 272 | const xin = in[i..]; |
| ... | ... | @@ -284,7 +284,7 @@ fn ChaChaVecImpl(comptime rounds_nb: usize, comptime degree: comptime_int) type |
| 284 | 284 | while (degree >= d and i + 64 * d <= out.len) : (i += 64 * d) { |
| 285 | 285 | chacha20Core(x[0..], ctx); |
| 286 | 286 | contextFeedback(&x, ctx); |
| 287 | hashToBytes(d, out[i..][0 .. 64 * d], x); | |
| 287 | hashToBytes(d, out[i..][0 .. 64 * d], &x); | |
| 288 | 288 | inline for (0..d) |d_| { |
| 289 | 289 | if (count64) { |
| 290 | 290 | const next = @addWithOverflow(ctx[3][4 * d_], d); |
| ... | ... | @@ -301,7 +301,7 @@ fn ChaChaVecImpl(comptime rounds_nb: usize, comptime degree: comptime_int) type |
| 301 | 301 | contextFeedback(&x, ctx); |
| 302 | 302 | |
| 303 | 303 | var buf: [64]u8 = undefined; |
| 304 | hashToBytes(1, buf[0..], x); | |
| 304 | hashToBytes(1, buf[0..], &x); | |
| 305 | 305 | @memcpy(out[i..], buf[0 .. out.len - i]); |
| 306 | 306 | } |
| 307 | 307 | } |
| ... | ... | @@ -394,7 +394,7 @@ fn ChaChaNonVecImpl(comptime rounds_nb: usize) type { |
| 394 | 394 | } |
| 395 | 395 | } |
| 396 | 396 | |
| 397 | fn hashToBytes(out: *[64]u8, x: BlockVec) void { | |
| 397 | fn hashToBytes(out: *[64]u8, x: *const BlockVec) void { | |
| 398 | 398 | for (0..4) |i| { |
| 399 | 399 | mem.writeInt(u32, out[16 * i + 0 ..][0..4], x[i * 4 + 0], .little); |
| 400 | 400 | mem.writeInt(u32, out[16 * i + 4 ..][0..4], x[i * 4 + 1], .little); |
| ... | ... | @@ -417,7 +417,7 @@ fn ChaChaNonVecImpl(comptime rounds_nb: usize) type { |
| 417 | 417 | while (i + 64 <= in.len) : (i += 64) { |
| 418 | 418 | chacha20Core(x[0..], ctx); |
| 419 | 419 | contextFeedback(&x, ctx); |
| 420 | hashToBytes(buf[0..], x); | |
| 420 | hashToBytes(buf[0..], &x); | |
| 421 | 421 | |
| 422 | 422 | var xout = out[i..]; |
| 423 | 423 | const xin = in[i..]; |
| ... | ... | @@ -438,7 +438,7 @@ fn ChaChaNonVecImpl(comptime rounds_nb: usize) type { |
| 438 | 438 | if (i < in.len) { |
| 439 | 439 | chacha20Core(x[0..], ctx); |
| 440 | 440 | contextFeedback(&x, ctx); |
| 441 | hashToBytes(buf[0..], x); | |
| 441 | hashToBytes(buf[0..], &x); | |
| 442 | 442 | |
| 443 | 443 | var xout = out[i..]; |
| 444 | 444 | const xin = in[i..]; |
| ... | ... | @@ -455,7 +455,7 @@ fn ChaChaNonVecImpl(comptime rounds_nb: usize) type { |
| 455 | 455 | while (i + 64 <= out.len) : (i += 64) { |
| 456 | 456 | chacha20Core(x[0..], ctx); |
| 457 | 457 | contextFeedback(&x, ctx); |
| 458 | hashToBytes(out[i..][0..64], x); | |
| 458 | hashToBytes(out[i..][0..64], &x); | |
| 459 | 459 | if (count64) { |
| 460 | 460 | const next = @addWithOverflow(ctx[12], 1); |
| 461 | 461 | ctx[12] = next[0]; |
| ... | ... | @@ -469,7 +469,7 @@ fn ChaChaNonVecImpl(comptime rounds_nb: usize) type { |
| 469 | 469 | contextFeedback(&x, ctx); |
| 470 | 470 | |
| 471 | 471 | var buf: [64]u8 = undefined; |
| 472 | hashToBytes(buf[0..], x); | |
| 472 | hashToBytes(buf[0..], &x); | |
| 473 | 473 | @memcpy(out[i..], buf[0 .. out.len - i]); |
| 474 | 474 | } |
| 475 | 475 | } |
lib/std/json/static.zig+5-24| ... | ... | @@ -440,10 +440,11 @@ pub fn innerParse( |
| 440 | 440 | } |
| 441 | 441 | }, |
| 442 | 442 | |
| 443 | .vector => |vecInfo| { | |
| 443 | .vector => |vector_info| { | |
| 444 | 444 | switch (try source.peekNextTokenType()) { |
| 445 | 445 | .array_begin => { |
| 446 | return internalParseVector(T, vecInfo.child, vecInfo.len, allocator, source, options); | |
| 446 | const A = [vector_info.len]vector_info.child; | |
| 447 | return try internalParseArray(A, vector_info.child, allocator, source, options); | |
| 447 | 448 | }, |
| 448 | 449 | else => return error.UnexpectedToken, |
| 449 | 450 | } |
| ... | ... | @@ -535,26 +536,6 @@ fn internalParseArray( |
| 535 | 536 | return r; |
| 536 | 537 | } |
| 537 | 538 | |
| 538 | fn internalParseVector( | |
| 539 | comptime T: type, | |
| 540 | comptime Child: type, | |
| 541 | comptime len: comptime_int, | |
| 542 | allocator: Allocator, | |
| 543 | source: anytype, | |
| 544 | options: ParseOptions, | |
| 545 | ) !T { | |
| 546 | assert(.array_begin == try source.next()); | |
| 547 | ||
| 548 | var r: T = undefined; | |
| 549 | inline for (0..len) |i| { | |
| 550 | r[i] = try innerParse(Child, allocator, source, options); | |
| 551 | } | |
| 552 | ||
| 553 | if (.array_end != try source.next()) return error.UnexpectedToken; | |
| 554 | ||
| 555 | return r; | |
| 556 | } | |
| 557 | ||
| 558 | 539 | /// This is an internal function called recursively |
| 559 | 540 | /// during the implementation of `parseFromValueLeaky`. |
| 560 | 541 | /// It is exposed primarily to enable custom `jsonParseFromValue()` methods to call back into the `parseFromValue*` system, |
| ... | ... | @@ -587,12 +568,12 @@ pub fn innerParseFromValue( |
| 587 | 568 | if (@round(f) != f) return error.InvalidNumber; |
| 588 | 569 | if (f > @as(@TypeOf(f), @floatFromInt(std.math.maxInt(T)))) return error.Overflow; |
| 589 | 570 | if (f < @as(@TypeOf(f), @floatFromInt(std.math.minInt(T)))) return error.Overflow; |
| 590 | return @as(T, @intFromFloat(f)); | |
| 571 | return @intFromFloat(f); | |
| 591 | 572 | }, |
| 592 | 573 | .integer => |i| { |
| 593 | 574 | if (i > std.math.maxInt(T)) return error.Overflow; |
| 594 | 575 | if (i < std.math.minInt(T)) return error.Overflow; |
| 595 | return @as(T, @intCast(i)); | |
| 576 | return @intCast(i); | |
| 596 | 577 | }, |
| 597 | 578 | .number_string, .string => |s| { |
| 598 | 579 | return sliceToInt(T, s); |
lib/std/meta.zig+1-6| ... | ... | @@ -742,12 +742,7 @@ pub fn eql(a: anytype, b: @TypeOf(a)) bool { |
| 742 | 742 | if (!eql(e, b[i])) return false; |
| 743 | 743 | return true; |
| 744 | 744 | }, |
| 745 | .vector => |info| { | |
| 746 | inline for (0..info.len) |i| { | |
| 747 | if (a[i] != b[i]) return false; | |
| 748 | } | |
| 749 | return true; | |
| 750 | }, | |
| 745 | .vector => return @reduce(.And, a == b), | |
| 751 | 746 | .pointer => |info| { |
| 752 | 747 | return switch (info.size) { |
| 753 | 748 | .one, .many, .c => a == b, |
lib/std/testing.zig+3-8| ... | ... | @@ -135,14 +135,9 @@ fn expectEqualInner(comptime T: type, expected: T, actual: T) !void { |
| 135 | 135 | .array => |array| try expectEqualSlices(array.child, &expected, &actual), |
| 136 | 136 | |
| 137 | 137 | .vector => |info| { |
| 138 | inline for (0..info.len) |i| { | |
| 139 | if (expected[i] != actual[i]) { | |
| 140 | print("index {d} incorrect. expected {any}, found {any}\n", .{ | |
| 141 | i, expected[i], actual[i], | |
| 142 | }); | |
| 143 | return error.TestExpectedEqual; | |
| 144 | } | |
| 145 | } | |
| 138 | const expect_array: [info.len]info.child = expected; | |
| 139 | const actual_array: [info.len]info.child = actual; | |
| 140 | try expectEqualSlices(info.child, &expect_array, &actual_array); | |
| 146 | 141 | }, |
| 147 | 142 | |
| 148 | 143 | .@"struct" => |structType| { |
lib/std/zon/Serializer.zig+15-16| ... | ... | @@ -157,13 +157,11 @@ pub fn valueArbitraryDepth(self: *Serializer, val: anytype, options: ValueOption |
| 157 | 157 | } |
| 158 | 158 | }, |
| 159 | 159 | .array => { |
| 160 | var container = try self.beginTuple( | |
| 161 | .{ .whitespace_style = .{ .fields = val.len } }, | |
| 162 | ); | |
| 163 | for (val) |item_val| { | |
| 164 | try container.fieldArbitraryDepth(item_val, options); | |
| 165 | } | |
| 166 | try container.end(); | |
| 160 | try valueArbitraryDepthArray(self, @TypeOf(val), &val, options); | |
| 161 | }, | |
| 162 | .vector => |vector| { | |
| 163 | const array: [vector.len]vector.child = val; | |
| 164 | try valueArbitraryDepthArray(self, @TypeOf(array), &array, options); | |
| 167 | 165 | }, |
| 168 | 166 | .@"struct" => |@"struct"| if (@"struct".is_tuple) { |
| 169 | 167 | var container = try self.beginTuple( |
| ... | ... | @@ -231,20 +229,21 @@ pub fn valueArbitraryDepth(self: *Serializer, val: anytype, options: ValueOption |
| 231 | 229 | } else { |
| 232 | 230 | try self.writer.writeAll("null"); |
| 233 | 231 | }, |
| 234 | .vector => |vector| { | |
| 235 | var container = try self.beginTuple( | |
| 236 | .{ .whitespace_style = .{ .fields = vector.len } }, | |
| 237 | ); | |
| 238 | inline for (0..vector.len) |i| { | |
| 239 | try container.fieldArbitraryDepth(val[i], options); | |
| 240 | } | |
| 241 | try container.end(); | |
| 242 | }, | |
| 243 | 232 | |
| 244 | 233 | else => comptime unreachable, |
| 245 | 234 | } |
| 246 | 235 | } |
| 247 | 236 | |
| 237 | fn valueArbitraryDepthArray(s: *Serializer, comptime A: type, array: *const A, options: ValueOptions) Error!void { | |
| 238 | var container = try s.beginTuple( | |
| 239 | .{ .whitespace_style = .{ .fields = array.len } }, | |
| 240 | ); | |
| 241 | for (array) |elem| { | |
| 242 | try container.fieldArbitraryDepth(elem, options); | |
| 243 | } | |
| 244 | try container.end(); | |
| 245 | } | |
| 246 | ||
| 248 | 247 | /// Serialize an integer. |
| 249 | 248 | pub fn int(self: *Serializer, val: anytype) Error!void { |
| 250 | 249 | try self.writer.printInt(val, 10, .lower, .{}); |
lib/std/zon/parse.zig+16-33| ... | ... | @@ -430,8 +430,12 @@ pub fn free(gpa: Allocator, value: anytype) void { |
| 430 | 430 | .many, .c => comptime unreachable, |
| 431 | 431 | } |
| 432 | 432 | }, |
| 433 | .array => for (value) |item| { | |
| 434 | free(gpa, item); | |
| 433 | .array => { | |
| 434 | freeArray(gpa, @TypeOf(value), &value); | |
| 435 | }, | |
| 436 | .vector => |vector| { | |
| 437 | const array: [vector.len]vector.child = value; | |
| 438 | freeArray(gpa, @TypeOf(array), &array); | |
| 435 | 439 | }, |
| 436 | 440 | .@"struct" => |@"struct"| inline for (@"struct".fields) |field| { |
| 437 | 441 | free(gpa, @field(value, field.name)); |
| ... | ... | @@ -446,12 +450,15 @@ pub fn free(gpa: Allocator, value: anytype) void { |
| 446 | 450 | .optional => if (value) |some| { |
| 447 | 451 | free(gpa, some); |
| 448 | 452 | }, |
| 449 | .vector => |vector| inline for (0..vector.len) |i| free(gpa, value[i]), | |
| 450 | 453 | .void => {}, |
| 451 | 454 | else => comptime unreachable, |
| 452 | 455 | } |
| 453 | 456 | } |
| 454 | 457 | |
| 458 | fn freeArray(gpa: Allocator, comptime A: type, array: *const A) void { | |
| 459 | for (array) |elem| free(gpa, elem); | |
| 460 | } | |
| 461 | ||
| 455 | 462 | fn requiresAllocator(T: type) bool { |
| 456 | 463 | _ = valid_types; |
| 457 | 464 | return switch (@typeInfo(T)) { |
| ... | ... | @@ -521,12 +528,15 @@ const Parser = struct { |
| 521 | 528 | else => comptime unreachable, |
| 522 | 529 | }, |
| 523 | 530 | .array => return self.parseArray(T, node), |
| 531 | .vector => |vector| { | |
| 532 | const A = [vector.len]vector.child; | |
| 533 | return try self.parseArray(A, node); | |
| 534 | }, | |
| 524 | 535 | .@"struct" => |@"struct"| if (@"struct".is_tuple) |
| 525 | 536 | return self.parseTuple(T, node) |
| 526 | 537 | else |
| 527 | 538 | return self.parseStruct(T, node), |
| 528 | 539 | .@"union" => return self.parseUnion(T, node), |
| 529 | .vector => return self.parseVector(T, node), | |
| 530 | 540 | |
| 531 | 541 | else => comptime unreachable, |
| 532 | 542 | } |
| ... | ... | @@ -999,33 +1009,6 @@ const Parser = struct { |
| 999 | 1009 | } |
| 1000 | 1010 | } |
| 1001 | 1011 | |
| 1002 | fn parseVector(self: *@This(), T: type, node: Zoir.Node.Index) !T { | |
| 1003 | const vector_info = @typeInfo(T).vector; | |
| 1004 | ||
| 1005 | const nodes: Zoir.Node.Index.Range = switch (node.get(self.zoir)) { | |
| 1006 | .array_literal => |nodes| nodes, | |
| 1007 | .empty_literal => .{ .start = node, .len = 0 }, | |
| 1008 | else => return error.WrongType, | |
| 1009 | }; | |
| 1010 | ||
| 1011 | var result: T = undefined; | |
| 1012 | ||
| 1013 | if (nodes.len != vector_info.len) { | |
| 1014 | return self.failNodeFmt( | |
| 1015 | node, | |
| 1016 | "expected {} vector elements; found {}", | |
| 1017 | .{ vector_info.len, nodes.len }, | |
| 1018 | ); | |
| 1019 | } | |
| 1020 | ||
| 1021 | inline for (0..vector_info.len) |i| { | |
| 1022 | errdefer inline for (0..i) |j| free(self.gpa, result[j]); | |
| 1023 | result[i] = try self.parseExpr(vector_info.child, nodes.at(@intCast(i))); | |
| 1024 | } | |
| 1025 | ||
| 1026 | return result; | |
| 1027 | } | |
| 1028 | ||
| 1029 | 1012 | fn failTokenFmt( |
| 1030 | 1013 | self: @This(), |
| 1031 | 1014 | token: Ast.TokenIndex, |
| ... | ... | @@ -3206,7 +3189,7 @@ test "std.zon vector" { |
| 3206 | 3189 | fromSlice(@Vector(2, f32), gpa, ".{0.5}", &diag, .{}), |
| 3207 | 3190 | ); |
| 3208 | 3191 | try std.testing.expectFmt( |
| 3209 | "1:2: error: expected 2 vector elements; found 1\n", | |
| 3192 | "1:2: error: expected 2 array elements; found 1\n", | |
| 3210 | 3193 | "{f}", |
| 3211 | 3194 | .{diag}, |
| 3212 | 3195 | ); |
| ... | ... | @@ -3221,7 +3204,7 @@ test "std.zon vector" { |
| 3221 | 3204 | fromSlice(@Vector(2, f32), gpa, ".{0.5, 1.5, 2.5}", &diag, .{}), |
| 3222 | 3205 | ); |
| 3223 | 3206 | try std.testing.expectFmt( |
| 3224 | "1:2: error: expected 2 vector elements; found 3\n", | |
| 3207 | "1:13: error: index 2 outside of array of length 2\n", | |
| 3225 | 3208 | "{f}", |
| 3226 | 3209 | .{diag}, |
| 3227 | 3210 | ); |
test/behavior/math.zig+1-4| ... | ... | @@ -139,10 +139,7 @@ fn expectVectorsEqual(a: anytype, b: anytype) !void { |
| 139 | 139 | const len_a = @typeInfo(@TypeOf(a)).vector.len; |
| 140 | 140 | const len_b = @typeInfo(@TypeOf(b)).vector.len; |
| 141 | 141 | try expect(len_a == len_b); |
| 142 | ||
| 143 | inline for (0..len_a) |i| { | |
| 144 | try expect(a[i] == b[i]); | |
| 145 | } | |
| 142 | try expect(@reduce(.And, a == b)); | |
| 146 | 143 | } |
| 147 | 144 | |
| 148 | 145 | test "@ctz" { |