mirror of
https://github.com/ziglang/zig.git
synced 2025-12-23 14:43:17 +00:00
Merge pull request #18729 from Vexu/fixes
Fix some generic{Reader,Writer} related issues
This commit is contained in:
commit
f4f8036ec0
@ -22368,7 +22368,10 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
|
|||||||
|
|
||||||
try sema.requireRuntimeBlock(block, src, operand_src);
|
try sema.requireRuntimeBlock(block, src, operand_src);
|
||||||
const err_int_ty = try mod.errorIntType();
|
const err_int_ty = try mod.errorIntType();
|
||||||
if (block.wantSafety() and !dest_ty.isAnyError(mod) and sema.mod.backendSupportsFeature(.error_set_has_value)) {
|
if (block.wantSafety() and !dest_ty.isAnyError(mod) and
|
||||||
|
dest_ty.toIntern() != .adhoc_inferred_error_set_type and
|
||||||
|
sema.mod.backendSupportsFeature(.error_set_has_value))
|
||||||
|
{
|
||||||
if (dest_tag == .ErrorUnion) {
|
if (dest_tag == .ErrorUnion) {
|
||||||
const err_code = try sema.analyzeErrUnionCode(block, operand_src, operand);
|
const err_code = try sema.analyzeErrUnionCode(block, operand_src, operand);
|
||||||
const err_int = try block.addBitCast(err_int_ty, err_code);
|
const err_int = try block.addBitCast(err_int_ty, err_code);
|
||||||
|
|||||||
@ -8694,10 +8694,10 @@ pub const FuncGen = struct {
|
|||||||
if (!result_is_ref) {
|
if (!result_is_ref) {
|
||||||
return self.dg.todo("implement bitcast vector to non-ref array", .{});
|
return self.dg.todo("implement bitcast vector to non-ref array", .{});
|
||||||
}
|
}
|
||||||
const array_ptr = try self.buildAllocaWorkaround(inst_ty, .default);
|
const alignment = inst_ty.abiAlignment(mod).toLlvm();
|
||||||
|
const array_ptr = try self.buildAllocaWorkaround(inst_ty, alignment);
|
||||||
const bitcast_ok = elem_ty.bitSize(mod) == elem_ty.abiSize(mod) * 8;
|
const bitcast_ok = elem_ty.bitSize(mod) == elem_ty.abiSize(mod) * 8;
|
||||||
if (bitcast_ok) {
|
if (bitcast_ok) {
|
||||||
const alignment = inst_ty.abiAlignment(mod).toLlvm();
|
|
||||||
_ = try self.wip.store(.normal, operand, array_ptr, alignment);
|
_ = try self.wip.store(.normal, operand, array_ptr, alignment);
|
||||||
} else {
|
} else {
|
||||||
// If the ABI size of the element type is not evenly divisible by size in bits;
|
// If the ABI size of the element type is not evenly divisible by size in bits;
|
||||||
|
|||||||
@ -1550,6 +1550,8 @@ pub const Value = struct {
|
|||||||
},
|
},
|
||||||
.ptr => |ptr| switch (ptr.addr) {
|
.ptr => |ptr| switch (ptr.addr) {
|
||||||
.eu_payload, .opt_payload => |base| Value.fromInterned(base).canMutateComptimeVarState(mod),
|
.eu_payload, .opt_payload => |base| Value.fromInterned(base).canMutateComptimeVarState(mod),
|
||||||
|
.anon_decl => |anon_decl| Value.fromInterned(anon_decl.val).canMutateComptimeVarState(mod),
|
||||||
|
.elem, .field => |base_index| Value.fromInterned(base_index.base).canMutateComptimeVarState(mod),
|
||||||
else => false,
|
else => false,
|
||||||
},
|
},
|
||||||
.opt => |opt| switch (opt.val) {
|
.opt => |opt| switch (opt.val) {
|
||||||
|
|||||||
@ -459,3 +459,77 @@ test "write empty array to end" {
|
|||||||
array[5..5].* = [_]u8{};
|
array[5..5].* = [_]u8{};
|
||||||
try testing.expectEqualStrings("hello", &array);
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@ -1027,3 +1027,15 @@ test "generic type constructed from inferred error set of unresolved function" {
|
|||||||
};
|
};
|
||||||
_ = std.io.multiWriter(.{S.writer()});
|
_ = 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);
|
||||||
|
}
|
||||||
|
|||||||
@ -1566,3 +1566,22 @@ test "@reduce on bool vector" {
|
|||||||
try std.testing.expect(@reduce(.And, a));
|
try std.testing.expect(@reduce(.And, a));
|
||||||
try std.testing.expect(@reduce(.And, b));
|
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);
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user