Commit 7fa88cc0a6

Andrew Kelley <andrew@ziglang.org>
2020-03-19 01:35:19
std lib fixups for new semantics
std lib tests are passing now
1 parent b5dba70
lib/std/hash/auto_hash.zig
@@ -40,7 +40,9 @@ pub fn hashPointer(hasher: var, key: var, comptime strat: HashStrategy) void {
             .DeepRecursive => hashArray(hasher, key, .DeepRecursive),
         },
 
-        .Many, .C, => switch (strat) {
+        .Many,
+        .C,
+        => switch (strat) {
             .Shallow => hash(hasher, @ptrToInt(key), .Shallow),
             else => @compileError(
                 \\ unknown-length pointers and C pointers cannot be hashed deeply.
@@ -236,9 +238,11 @@ test "hash slice shallow" {
     defer std.testing.allocator.destroy(array1);
     array1.* = [_]u32{ 1, 2, 3, 4, 5, 6 };
     const array2 = [_]u32{ 1, 2, 3, 4, 5, 6 };
-    const a = array1[0..];
-    const b = array2[0..];
-    const c = array1[0..3];
+    // TODO audit deep/shallow - maybe it has the wrong behavior with respect to array pointers and slices
+    var runtime_zero: usize = 0;
+    const a = array1[runtime_zero..];
+    const b = array2[runtime_zero..];
+    const c = array1[runtime_zero..3];
     testing.expect(testHashShallow(a) == testHashShallow(a));
     testing.expect(testHashShallow(a) != testHashShallow(array1));
     testing.expect(testHashShallow(a) != testHashShallow(b));
lib/std/meta/trait.zig
@@ -230,9 +230,10 @@ pub fn isSingleItemPtr(comptime T: type) bool {
 
 test "std.meta.trait.isSingleItemPtr" {
     const array = [_]u8{0} ** 10;
-    testing.expect(isSingleItemPtr(@TypeOf(&array[0])));
-    testing.expect(!isSingleItemPtr(@TypeOf(array)));
-    testing.expect(!isSingleItemPtr(@TypeOf(array[0..1])));
+    comptime testing.expect(isSingleItemPtr(@TypeOf(&array[0])));
+    comptime testing.expect(!isSingleItemPtr(@TypeOf(array)));
+    var runtime_zero: usize = 0;
+    testing.expect(!isSingleItemPtr(@TypeOf(array[runtime_zero..1])));
 }
 
 pub fn isManyItemPtr(comptime T: type) bool {
@@ -259,7 +260,8 @@ pub fn isSlice(comptime T: type) bool {
 
 test "std.meta.trait.isSlice" {
     const array = [_]u8{0} ** 10;
-    testing.expect(isSlice(@TypeOf(array[0..])));
+    var runtime_zero: usize = 0;
+    testing.expect(isSlice(@TypeOf(array[runtime_zero..])));
     testing.expect(!isSlice(@TypeOf(array)));
     testing.expect(!isSlice(@TypeOf(&array[0])));
 }
@@ -276,7 +278,7 @@ pub fn isIndexable(comptime T: type) bool {
 
 test "std.meta.trait.isIndexable" {
     const array = [_]u8{0} ** 10;
-    const slice = array[0..];
+    const slice = @as([]const u8, &array);
 
     testing.expect(isIndexable(@TypeOf(array)));
     testing.expect(isIndexable(@TypeOf(&array)));
lib/std/fmt.zig
@@ -1223,7 +1223,8 @@ test "slice" {
         try testFmt("slice: abc\n", "slice: {}\n", .{value});
     }
     {
-        const value = @intToPtr([*]align(1) const []const u8, 0xdeadbeef)[0..0];
+        var runtime_zero: usize = 0;
+        const value = @intToPtr([*]align(1) const []const u8, 0xdeadbeef)[runtime_zero..runtime_zero];
         try testFmt("slice: []const u8@deadbeef\n", "slice: {}\n", .{value});
     }
 
lib/std/fs.zig
@@ -360,7 +360,7 @@ pub const Dir = struct {
                     if (self.index >= self.end_index) {
                         const rc = os.system.getdirentries(
                             self.dir.fd,
-                            self.buf[0..].ptr,
+                            &self.buf,
                             self.buf.len,
                             &self.seek,
                         );
lib/std/json.zig
@@ -2249,11 +2249,16 @@ pub const StringifyOptions = struct {
     // TODO: allow picking if []u8 is string or array?
 };
 
+pub const StringifyError = error{
+    TooMuchData,
+    DifferentData,
+};
+
 pub fn stringify(
     value: var,
     options: StringifyOptions,
     out_stream: var,
-) !void {
+) StringifyError!void {
     const T = @TypeOf(value);
     switch (@typeInfo(T)) {
         .Float, .ComptimeFloat => {
@@ -2320,9 +2325,15 @@ pub fn stringify(
             return;
         },
         .Pointer => |ptr_info| switch (ptr_info.size) {
-            .One => {
-                // TODO: avoid loops?
-                return try stringify(value.*, options, out_stream);
+            .One => switch (@typeInfo(ptr_info.child)) {
+                .Array => {
+                    const Slice = []const std.meta.Elem(ptr_info.child);
+                    return stringify(@as(Slice, value), options, out_stream);
+                },
+                else => {
+                    // TODO: avoid loops?
+                    return stringify(value.*, options, out_stream);
+                },
             },
             // TODO: .Many when there is a sentinel (waiting for https://github.com/ziglang/zig/pull/3972)
             .Slice => {
@@ -2381,9 +2392,7 @@ pub fn stringify(
             },
             else => @compileError("Unable to stringify type '" ++ @typeName(T) ++ "'"),
         },
-        .Array => |info| {
-            return try stringify(value[0..], options, out_stream);
-        },
+        .Array => return stringify(&value, options, out_stream),
         else => @compileError("Unable to stringify type '" ++ @typeName(T) ++ "'"),
     }
     unreachable;
lib/std/mem.zig
@@ -1586,24 +1586,24 @@ pub fn nativeToBig(comptime T: type, x: T) T {
 }
 
 fn AsBytesReturnType(comptime P: type) type {
-    if (comptime !trait.isSingleItemPtr(P))
+    if (!trait.isSingleItemPtr(P))
         @compileError("expected single item pointer, passed " ++ @typeName(P));
 
-    const size = @as(usize, @sizeOf(meta.Child(P)));
-    const alignment = comptime meta.alignment(P);
+    const size = @sizeOf(meta.Child(P));
+    const alignment = meta.alignment(P);
 
     if (alignment == 0) {
-        if (comptime trait.isConstPtr(P))
+        if (trait.isConstPtr(P))
             return *const [size]u8;
         return *[size]u8;
     }
 
-    if (comptime trait.isConstPtr(P))
+    if (trait.isConstPtr(P))
         return *align(alignment) const [size]u8;
     return *align(alignment) [size]u8;
 }
 
-///Given a pointer to a single item, returns a slice of the underlying bytes, preserving constness.
+/// Given a pointer to a single item, returns a slice of the underlying bytes, preserving constness.
 pub fn asBytes(ptr: var) AsBytesReturnType(@TypeOf(ptr)) {
     const P = @TypeOf(ptr);
     return @ptrCast(AsBytesReturnType(P), ptr);
@@ -1841,7 +1841,7 @@ pub fn sliceAsBytes(slice: var) SliceAsBytesReturnType(@TypeOf(slice)) {
 
     const cast_target = if (comptime trait.isConstPtr(Slice)) [*]align(alignment) const u8 else [*]align(alignment) u8;
 
-    return @ptrCast(cast_target, slice)[0 .. slice.len * @sizeOf(meta.Child(Slice))];
+    return @ptrCast(cast_target, slice)[0 .. slice.len * @sizeOf(meta.Elem(Slice))];
 }
 
 test "sliceAsBytes" {
@@ -1911,39 +1911,6 @@ test "sliceAsBytes and bytesAsSlice back" {
     testing.expect(bytes[11] == math.maxInt(u8));
 }
 
-fn SubArrayPtrReturnType(comptime T: type, comptime length: usize) type {
-    if (trait.isConstPtr(T))
-        return *const [length]meta.Child(meta.Child(T));
-    return *[length]meta.Child(meta.Child(T));
-}
-
-/// Given a pointer to an array, returns a pointer to a portion of that array, preserving constness.
-/// TODO this will be obsoleted by https://github.com/ziglang/zig/issues/863
-pub fn subArrayPtr(
-    ptr: var,
-    comptime start: usize,
-    comptime length: usize,
-) SubArrayPtrReturnType(@TypeOf(ptr), length) {
-    assert(start + length <= ptr.*.len);
-
-    const ReturnType = SubArrayPtrReturnType(@TypeOf(ptr), length);
-    const T = meta.Child(meta.Child(@TypeOf(ptr)));
-    return @ptrCast(ReturnType, &ptr[start]);
-}
-
-test "subArrayPtr" {
-    const a1: [6]u8 = "abcdef".*;
-    const sub1 = subArrayPtr(&a1, 2, 3);
-    testing.expect(eql(u8, sub1, "cde"));
-
-    var a2: [6]u8 = "abcdef".*;
-    var sub2 = subArrayPtr(&a2, 2, 3);
-
-    testing.expect(eql(u8, sub2, "cde"));
-    sub2[1] = 'X';
-    testing.expect(eql(u8, &a2, "abcXef"));
-}
-
 /// Round an address up to the nearest aligned address
 /// The alignment must be a power of 2 and greater than 0.
 pub fn alignForward(addr: usize, alignment: usize) usize {
lib/std/net.zig
@@ -612,8 +612,7 @@ fn linuxLookupName(
         } else {
             mem.copy(u8, &sa6.addr, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff");
             mem.copy(u8, &da6.addr, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff");
-            // TODO https://github.com/ziglang/zig/issues/863
-            mem.writeIntNative(u32, @ptrCast(*[4]u8, da6.addr[12..].ptr), addr.addr.in.addr);
+            mem.writeIntNative(u32, da6.addr[12..], addr.addr.in.addr);
             da4.addr = addr.addr.in.addr;
             da = @ptrCast(*os.sockaddr, &da4);
             dalen = @sizeOf(os.sockaddr_in);
@@ -821,7 +820,7 @@ fn linuxLookupNameFromHosts(
             // Skip to the delimiter in the stream, to fix parsing
             try stream.skipUntilDelimiterOrEof('\n');
             // Use the truncated line. A truncated comment or hostname will be handled correctly.
-            break :blk line_buf[0..];
+            break :blk @as([]u8, &line_buf); // TODO the cast should not be necessary
         },
         else => |e| return e,
     }) |line| {
@@ -958,7 +957,8 @@ fn linuxLookupNameFromDns(
         }
     }
 
-    var ap = [2][]u8{ apbuf[0][0..0], apbuf[1][0..0] };
+    var hack: usize = 0; // TODO remove this hack
+    var ap = [2][]u8{ apbuf[0][0..hack], apbuf[1][0..hack] };
     try resMSendRc(qp[0..nq], ap[0..nq], apbuf[0..nq], rc);
 
     var i: usize = 0;
@@ -1015,7 +1015,7 @@ fn getResolvConf(allocator: *mem.Allocator, rc: *ResolvConf) !void {
             // Skip to the delimiter in the stream, to fix parsing
             try stream.skipUntilDelimiterOrEof('\n');
             // Give an empty line to the while loop, which will be skipped.
-            break :blk line_buf[0..0];
+            break :blk @as([]u8, line_buf[0..0]); // TODO the cast should not be necessary
         },
         else => |e| return e,
     }) |line| {
src/ir.cpp
@@ -14633,7 +14633,7 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr,
         return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type);
     }
 
-    // *[N]T to ?[]const T
+    // *[N]T to ?[]T
     if (wanted_type->id == ZigTypeIdOptional &&
         is_slice(wanted_type->data.maybe.child_type) &&
         actual_type->id == ZigTypeIdPointer &&