Merge pull request #18729 from Vexu/fixes

Fix some generic{Reader,Writer} related issues
This commit is contained in:
Andrew Kelley
2024-01-29 13:07:37 -08:00
committed by GitHub
6 changed files with 113 additions and 3 deletions

View File

@@ -459,3 +459,77 @@ test "write empty array to end" {
array[5..5].* = [_]u8{};
try testing.expectEqualStrings("hello", &array);
}
fn doublePtrTest() !void {
var a: u32 = 0;
const ptr = &a;
const double_ptr = &ptr;
setDoublePtr(double_ptr, 1);
setDoublePtr(double_ptr, 2);
setDoublePtr(double_ptr, 1);
try std.testing.expect(a == 1);
}
fn setDoublePtr(ptr: *const *const u32, value: u32) void {
setPtr(ptr.*, value);
}
fn setPtr(ptr: *const u32, value: u32) void {
const mut_ptr: *u32 = @constCast(ptr);
mut_ptr.* = value;
}
test "double pointer can mutate comptime state" {
try comptime doublePtrTest();
}
fn GenericIntApplier(
comptime Context: type,
comptime applyFn: fn (context: Context, arg: u32) void,
) type {
return struct {
context: Context,
const Self = @This();
inline fn any(self: *const Self) IntApplier {
return .{
.context = @ptrCast(&self.context),
.applyFn = typeErasedApplyFn,
};
}
fn typeErasedApplyFn(context: *const anyopaque, arg: u32) void {
const ptr: *const Context = @alignCast(@ptrCast(context));
applyFn(ptr.*, arg);
}
};
}
const IntApplier = struct {
context: *const anyopaque,
applyFn: *const fn (context: *const anyopaque, arg: u32) void,
fn apply(ia: IntApplier, arg: u32) void {
ia.applyFn(ia.context, arg);
}
};
const Accumulator = struct {
value: u32,
const Applier = GenericIntApplier(*u32, add);
fn applier(a: *Accumulator) Applier {
return .{ .context = &a.value };
}
fn add(context: *u32, arg: u32) void {
context.* += arg;
}
};
fn fieldPtrTest() u32 {
var a: Accumulator = .{ .value = 0 };
const applier = a.applier();
applier.any().apply(1);
applier.any().apply(1);
return a.value;
}
test "pointer in aggregate field can mutate comptime state" {
try comptime std.testing.expect(fieldPtrTest() == 2);
}

View File

@@ -1027,3 +1027,15 @@ test "generic type constructed from inferred error set of unresolved function" {
};
_ = std.io.multiWriter(.{S.writer()});
}
test "errorCast to adhoc inferred error set" {
const S = struct {
inline fn baz() !i32 {
return @errorCast(err());
}
fn err() anyerror!i32 {
return 1234;
}
};
try std.testing.expect((try S.baz()) == 1234);
}

View File

@@ -1566,3 +1566,22 @@ test "@reduce on bool vector" {
try std.testing.expect(@reduce(.And, a));
try std.testing.expect(@reduce(.And, b));
}
test "bitcast vector to array of smaller vectors" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
const u8x32 = @Vector(32, u8);
const u8x64 = @Vector(64, u8);
const S = struct {
fn doTheTest(input_vec: u8x64) !void {
try compare(@bitCast(input_vec));
}
fn compare(chunks: [2]u8x32) !void {
try expectEqual(@as(u8x32, @splat(1)), chunks[0]);
try expectEqual(@as(u8x32, @splat(2)), chunks[1]);
}
};
const input: u8x64 = @bitCast([2]u8x32{ @splat(1), @splat(2) });
try S.doTheTest(input);
}