authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-18 20:35:19-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-19 09:53:55-04:00
log7fa88cc0a678a3690b61054030f5597b623964a4
treea1cdaabfbbe0fe8b240691a9b1921245973f5107
parentb5dba702fff35c2d9aa86c9d5dd93a4a38d3b75b
signaturelock-open Commit is signed but in an unrecognized format.

std lib fixups for new semantics

std lib tests are passing now

8 files changed, 47 insertions(+), 64 deletions(-)

lib/std/fmt.zig+2-1
...@@ -1223,7 +1223,8 @@ test "slice" {...@@ -1223,7 +1223,8 @@ test "slice" {
1223 try testFmt("slice: abc\n", "slice: {}\n", .{value});1223 try testFmt("slice: abc\n", "slice: {}\n", .{value});
1224 }1224 }
1225 {1225 {
1226 const value = @intToPtr([*]align(1) const []const u8, 0xdeadbeef)[0..0];1226 var runtime_zero: usize = 0;
1227 const value = @intToPtr([*]align(1) const []const u8, 0xdeadbeef)[runtime_zero..runtime_zero];
1227 try testFmt("slice: []const u8@deadbeef\n", "slice: {}\n", .{value});1228 try testFmt("slice: []const u8@deadbeef\n", "slice: {}\n", .{value});
1228 }1229 }
12291230
lib/std/fs.zig+1-1
...@@ -360,7 +360,7 @@ pub const Dir = struct {...@@ -360,7 +360,7 @@ pub const Dir = struct {
360 if (self.index >= self.end_index) {360 if (self.index >= self.end_index) {
361 const rc = os.system.getdirentries(361 const rc = os.system.getdirentries(
362 self.dir.fd,362 self.dir.fd,
363 self.buf[0..].ptr,363 &self.buf,
364 self.buf.len,364 self.buf.len,
365 &self.seek,365 &self.seek,
366 );366 );
lib/std/hash/auto_hash.zig+8-4
...@@ -40,7 +40,9 @@ pub fn hashPointer(hasher: var, key: var, comptime strat: HashStrategy) void {...@@ -40,7 +40,9 @@ pub fn hashPointer(hasher: var, key: var, comptime strat: HashStrategy) void {
40 .DeepRecursive => hashArray(hasher, key, .DeepRecursive),40 .DeepRecursive => hashArray(hasher, key, .DeepRecursive),
41 },41 },
4242
43 .Many, .C, => switch (strat) {43 .Many,
44 .C,
45 => switch (strat) {
44 .Shallow => hash(hasher, @ptrToInt(key), .Shallow),46 .Shallow => hash(hasher, @ptrToInt(key), .Shallow),
45 else => @compileError(47 else => @compileError(
46 \\ unknown-length pointers and C pointers cannot be hashed deeply.48 \\ unknown-length pointers and C pointers cannot be hashed deeply.
...@@ -236,9 +238,11 @@ test "hash slice shallow" {...@@ -236,9 +238,11 @@ test "hash slice shallow" {
236 defer std.testing.allocator.destroy(array1);238 defer std.testing.allocator.destroy(array1);
237 array1.* = [_]u32{ 1, 2, 3, 4, 5, 6 };239 array1.* = [_]u32{ 1, 2, 3, 4, 5, 6 };
238 const array2 = [_]u32{ 1, 2, 3, 4, 5, 6 };240 const array2 = [_]u32{ 1, 2, 3, 4, 5, 6 };
239 const a = array1[0..];241 // TODO audit deep/shallow - maybe it has the wrong behavior with respect to array pointers and slices
240 const b = array2[0..];242 var runtime_zero: usize = 0;
241 const c = array1[0..3];243 const a = array1[runtime_zero..];
244 const b = array2[runtime_zero..];
245 const c = array1[runtime_zero..3];
242 testing.expect(testHashShallow(a) == testHashShallow(a));246 testing.expect(testHashShallow(a) == testHashShallow(a));
243 testing.expect(testHashShallow(a) != testHashShallow(array1));247 testing.expect(testHashShallow(a) != testHashShallow(array1));
244 testing.expect(testHashShallow(a) != testHashShallow(b));248 testing.expect(testHashShallow(a) != testHashShallow(b));
lib/std/json.zig+16-7
...@@ -2249,11 +2249,16 @@ pub const StringifyOptions = struct {...@@ -2249,11 +2249,16 @@ pub const StringifyOptions = struct {
2249 // TODO: allow picking if []u8 is string or array?2249 // TODO: allow picking if []u8 is string or array?
2250};2250};
22512251
2252pub const StringifyError = error{
2253 TooMuchData,
2254 DifferentData,
2255};
2256
2252pub fn stringify(2257pub fn stringify(
2253 value: var,2258 value: var,
2254 options: StringifyOptions,2259 options: StringifyOptions,
2255 out_stream: var,2260 out_stream: var,
2256) !void {2261) StringifyError!void {
2257 const T = @TypeOf(value);2262 const T = @TypeOf(value);
2258 switch (@typeInfo(T)) {2263 switch (@typeInfo(T)) {
2259 .Float, .ComptimeFloat => {2264 .Float, .ComptimeFloat => {
...@@ -2320,9 +2325,15 @@ pub fn stringify(...@@ -2320,9 +2325,15 @@ pub fn stringify(
2320 return;2325 return;
2321 },2326 },
2322 .Pointer => |ptr_info| switch (ptr_info.size) {2327 .Pointer => |ptr_info| switch (ptr_info.size) {
2323 .One => {2328 .One => switch (@typeInfo(ptr_info.child)) {
2324 // TODO: avoid loops?2329 .Array => {
2325 return try stringify(value.*, options, out_stream);2330 const Slice = []const std.meta.Elem(ptr_info.child);
2331 return stringify(@as(Slice, value), options, out_stream);
2332 },
2333 else => {
2334 // TODO: avoid loops?
2335 return stringify(value.*, options, out_stream);
2336 },
2326 },2337 },
2327 // TODO: .Many when there is a sentinel (waiting for https://github.com/ziglang/zig/pull/3972)2338 // TODO: .Many when there is a sentinel (waiting for https://github.com/ziglang/zig/pull/3972)
2328 .Slice => {2339 .Slice => {
...@@ -2381,9 +2392,7 @@ pub fn stringify(...@@ -2381,9 +2392,7 @@ pub fn stringify(
2381 },2392 },
2382 else => @compileError("Unable to stringify type '" ++ @typeName(T) ++ "'"),2393 else => @compileError("Unable to stringify type '" ++ @typeName(T) ++ "'"),
2383 },2394 },
2384 .Array => |info| {2395 .Array => return stringify(&value, options, out_stream),
2385 return try stringify(value[0..], options, out_stream);
2386 },
2387 else => @compileError("Unable to stringify type '" ++ @typeName(T) ++ "'"),2396 else => @compileError("Unable to stringify type '" ++ @typeName(T) ++ "'"),
2388 }2397 }
2389 unreachable;2398 unreachable;
lib/std/mem.zig+7-40
...@@ -1586,24 +1586,24 @@ pub fn nativeToBig(comptime T: type, x: T) T {...@@ -1586,24 +1586,24 @@ pub fn nativeToBig(comptime T: type, x: T) T {
1586}1586}
15871587
1588fn AsBytesReturnType(comptime P: type) type {1588fn AsBytesReturnType(comptime P: type) type {
1589 if (comptime !trait.isSingleItemPtr(P))1589 if (!trait.isSingleItemPtr(P))
1590 @compileError("expected single item pointer, passed " ++ @typeName(P));1590 @compileError("expected single item pointer, passed " ++ @typeName(P));
15911591
1592 const size = @as(usize, @sizeOf(meta.Child(P)));1592 const size = @sizeOf(meta.Child(P));
1593 const alignment = comptime meta.alignment(P);1593 const alignment = meta.alignment(P);
15941594
1595 if (alignment == 0) {1595 if (alignment == 0) {
1596 if (comptime trait.isConstPtr(P))1596 if (trait.isConstPtr(P))
1597 return *const [size]u8;1597 return *const [size]u8;
1598 return *[size]u8;1598 return *[size]u8;
1599 }1599 }
16001600
1601 if (comptime trait.isConstPtr(P))1601 if (trait.isConstPtr(P))
1602 return *align(alignment) const [size]u8;1602 return *align(alignment) const [size]u8;
1603 return *align(alignment) [size]u8;1603 return *align(alignment) [size]u8;
1604}1604}
16051605
1606///Given a pointer to a single item, returns a slice of the underlying bytes, preserving constness.1606/// Given a pointer to a single item, returns a slice of the underlying bytes, preserving constness.
1607pub fn asBytes(ptr: var) AsBytesReturnType(@TypeOf(ptr)) {1607pub fn asBytes(ptr: var) AsBytesReturnType(@TypeOf(ptr)) {
1608 const P = @TypeOf(ptr);1608 const P = @TypeOf(ptr);
1609 return @ptrCast(AsBytesReturnType(P), ptr);1609 return @ptrCast(AsBytesReturnType(P), ptr);
...@@ -1841,7 +1841,7 @@ pub fn sliceAsBytes(slice: var) SliceAsBytesReturnType(@TypeOf(slice)) {...@@ -1841,7 +1841,7 @@ pub fn sliceAsBytes(slice: var) SliceAsBytesReturnType(@TypeOf(slice)) {
18411841
1842 const cast_target = if (comptime trait.isConstPtr(Slice)) [*]align(alignment) const u8 else [*]align(alignment) u8;1842 const cast_target = if (comptime trait.isConstPtr(Slice)) [*]align(alignment) const u8 else [*]align(alignment) u8;
18431843
1844 return @ptrCast(cast_target, slice)[0 .. slice.len * @sizeOf(meta.Child(Slice))];1844 return @ptrCast(cast_target, slice)[0 .. slice.len * @sizeOf(meta.Elem(Slice))];
1845}1845}
18461846
1847test "sliceAsBytes" {1847test "sliceAsBytes" {
...@@ -1911,39 +1911,6 @@ test "sliceAsBytes and bytesAsSlice back" {...@@ -1911,39 +1911,6 @@ test "sliceAsBytes and bytesAsSlice back" {
1911 testing.expect(bytes[11] == math.maxInt(u8));1911 testing.expect(bytes[11] == math.maxInt(u8));
1912}1912}
19131913
1914fn SubArrayPtrReturnType(comptime T: type, comptime length: usize) type {
1915 if (trait.isConstPtr(T))
1916 return *const [length]meta.Child(meta.Child(T));
1917 return *[length]meta.Child(meta.Child(T));
1918}
1919
1920/// Given a pointer to an array, returns a pointer to a portion of that array, preserving constness.
1921/// TODO this will be obsoleted by https://github.com/ziglang/zig/issues/863
1922pub fn subArrayPtr(
1923 ptr: var,
1924 comptime start: usize,
1925 comptime length: usize,
1926) SubArrayPtrReturnType(@TypeOf(ptr), length) {
1927 assert(start + length <= ptr.*.len);
1928
1929 const ReturnType = SubArrayPtrReturnType(@TypeOf(ptr), length);
1930 const T = meta.Child(meta.Child(@TypeOf(ptr)));
1931 return @ptrCast(ReturnType, &ptr[start]);
1932}
1933
1934test "subArrayPtr" {
1935 const a1: [6]u8 = "abcdef".*;
1936 const sub1 = subArrayPtr(&a1, 2, 3);
1937 testing.expect(eql(u8, sub1, "cde"));
1938
1939 var a2: [6]u8 = "abcdef".*;
1940 var sub2 = subArrayPtr(&a2, 2, 3);
1941
1942 testing.expect(eql(u8, sub2, "cde"));
1943 sub2[1] = 'X';
1944 testing.expect(eql(u8, &a2, "abcXef"));
1945}
1946
1947/// Round an address up to the nearest aligned address1914/// Round an address up to the nearest aligned address
1948/// The alignment must be a power of 2 and greater than 0.1915/// The alignment must be a power of 2 and greater than 0.
1949pub fn alignForward(addr: usize, alignment: usize) usize {1916pub fn alignForward(addr: usize, alignment: usize) usize {
lib/std/meta/trait.zig+7-5
...@@ -230,9 +230,10 @@ pub fn isSingleItemPtr(comptime T: type) bool {...@@ -230,9 +230,10 @@ pub fn isSingleItemPtr(comptime T: type) bool {
230230
231test "std.meta.trait.isSingleItemPtr" {231test "std.meta.trait.isSingleItemPtr" {
232 const array = [_]u8{0} ** 10;232 const array = [_]u8{0} ** 10;
233 testing.expect(isSingleItemPtr(@TypeOf(&array[0])));233 comptime testing.expect(isSingleItemPtr(@TypeOf(&array[0])));
234 testing.expect(!isSingleItemPtr(@TypeOf(array)));234 comptime testing.expect(!isSingleItemPtr(@TypeOf(array)));
235 testing.expect(!isSingleItemPtr(@TypeOf(array[0..1])));235 var runtime_zero: usize = 0;
236 testing.expect(!isSingleItemPtr(@TypeOf(array[runtime_zero..1])));
236}237}
237238
238pub fn isManyItemPtr(comptime T: type) bool {239pub fn isManyItemPtr(comptime T: type) bool {
...@@ -259,7 +260,8 @@ pub fn isSlice(comptime T: type) bool {...@@ -259,7 +260,8 @@ pub fn isSlice(comptime T: type) bool {
259260
260test "std.meta.trait.isSlice" {261test "std.meta.trait.isSlice" {
261 const array = [_]u8{0} ** 10;262 const array = [_]u8{0} ** 10;
262 testing.expect(isSlice(@TypeOf(array[0..])));263 var runtime_zero: usize = 0;
264 testing.expect(isSlice(@TypeOf(array[runtime_zero..])));
263 testing.expect(!isSlice(@TypeOf(array)));265 testing.expect(!isSlice(@TypeOf(array)));
264 testing.expect(!isSlice(@TypeOf(&array[0])));266 testing.expect(!isSlice(@TypeOf(&array[0])));
265}267}
...@@ -276,7 +278,7 @@ pub fn isIndexable(comptime T: type) bool {...@@ -276,7 +278,7 @@ pub fn isIndexable(comptime T: type) bool {
276278
277test "std.meta.trait.isIndexable" {279test "std.meta.trait.isIndexable" {
278 const array = [_]u8{0} ** 10;280 const array = [_]u8{0} ** 10;
279 const slice = array[0..];281 const slice = @as([]const u8, &array);
280282
281 testing.expect(isIndexable(@TypeOf(array)));283 testing.expect(isIndexable(@TypeOf(array)));
282 testing.expect(isIndexable(@TypeOf(&array)));284 testing.expect(isIndexable(@TypeOf(&array)));
lib/std/net.zig+5-5
...@@ -612,8 +612,7 @@ fn linuxLookupName(...@@ -612,8 +612,7 @@ fn linuxLookupName(
612 } else {612 } else {
613 mem.copy(u8, &sa6.addr, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff");613 mem.copy(u8, &sa6.addr, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff");
614 mem.copy(u8, &da6.addr, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff");614 mem.copy(u8, &da6.addr, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff");
615 // TODO https://github.com/ziglang/zig/issues/863615 mem.writeIntNative(u32, da6.addr[12..], addr.addr.in.addr);
616 mem.writeIntNative(u32, @ptrCast(*[4]u8, da6.addr[12..].ptr), addr.addr.in.addr);
617 da4.addr = addr.addr.in.addr;616 da4.addr = addr.addr.in.addr;
618 da = @ptrCast(*os.sockaddr, &da4);617 da = @ptrCast(*os.sockaddr, &da4);
619 dalen = @sizeOf(os.sockaddr_in);618 dalen = @sizeOf(os.sockaddr_in);
...@@ -821,7 +820,7 @@ fn linuxLookupNameFromHosts(...@@ -821,7 +820,7 @@ fn linuxLookupNameFromHosts(
821 // Skip to the delimiter in the stream, to fix parsing820 // Skip to the delimiter in the stream, to fix parsing
822 try stream.skipUntilDelimiterOrEof('\n');821 try stream.skipUntilDelimiterOrEof('\n');
823 // Use the truncated line. A truncated comment or hostname will be handled correctly.822 // Use the truncated line. A truncated comment or hostname will be handled correctly.
824 break :blk line_buf[0..];823 break :blk @as([]u8, &line_buf); // TODO the cast should not be necessary
825 },824 },
826 else => |e| return e,825 else => |e| return e,
827 }) |line| {826 }) |line| {
...@@ -958,7 +957,8 @@ fn linuxLookupNameFromDns(...@@ -958,7 +957,8 @@ fn linuxLookupNameFromDns(
958 }957 }
959 }958 }
960959
961 var ap = [2][]u8{ apbuf[0][0..0], apbuf[1][0..0] };960 var hack: usize = 0; // TODO remove this hack
961 var ap = [2][]u8{ apbuf[0][0..hack], apbuf[1][0..hack] };
962 try resMSendRc(qp[0..nq], ap[0..nq], apbuf[0..nq], rc);962 try resMSendRc(qp[0..nq], ap[0..nq], apbuf[0..nq], rc);
963963
964 var i: usize = 0;964 var i: usize = 0;
...@@ -1015,7 +1015,7 @@ fn getResolvConf(allocator: *mem.Allocator, rc: *ResolvConf) !void {...@@ -1015,7 +1015,7 @@ fn getResolvConf(allocator: *mem.Allocator, rc: *ResolvConf) !void {
1015 // Skip to the delimiter in the stream, to fix parsing1015 // Skip to the delimiter in the stream, to fix parsing
1016 try stream.skipUntilDelimiterOrEof('\n');1016 try stream.skipUntilDelimiterOrEof('\n');
1017 // Give an empty line to the while loop, which will be skipped.1017 // Give an empty line to the while loop, which will be skipped.
1018 break :blk line_buf[0..0];1018 break :blk @as([]u8, line_buf[0..0]); // TODO the cast should not be necessary
1019 },1019 },
1020 else => |e| return e,1020 else => |e| return e,
1021 }) |line| {1021 }) |line| {
src/ir.cpp+1-1
...@@ -14633,7 +14633,7 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr,...@@ -14633,7 +14633,7 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr,
14633 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type);14633 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type);
14634 }14634 }
1463514635
14636 // *[N]T to ?[]const T14636 // *[N]T to ?[]T
14637 if (wanted_type->id == ZigTypeIdOptional &&14637 if (wanted_type->id == ZigTypeIdOptional &&
14638 is_slice(wanted_type->data.maybe.child_type) &&14638 is_slice(wanted_type->data.maybe.child_type) &&
14639 actual_type->id == ZigTypeIdPointer &&14639 actual_type->id == ZigTypeIdPointer &&