std lib fixups for new semantics

std lib tests are passing now
This commit is contained in:
Andrew Kelley 2020-03-18 20:35:19 -04:00
parent b5dba702ff
commit 7fa88cc0a6
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
8 changed files with 47 additions and 64 deletions

View File

@ -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});
}

View File

@ -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,
);

View File

@ -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));

View File

@ -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;

View File

@ -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 {

View File

@ -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)));

View File

@ -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| {

View File

@ -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 &&