Skip to content

Commit

Permalink
Merge pull request #21390 from xdBronch/push-tvovpsxztrqn
Browse files Browse the repository at this point in the history
make decl literals work with single item pointers
  • Loading branch information
mlugg authored Sep 14, 2024
2 parents 8ddce90 + bc16143 commit 4d81e8e
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 7 deletions.
1 change: 1 addition & 0 deletions src/Sema.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8996,6 +8996,7 @@ fn zirDeclLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index, do_coerce: b
while (true) switch (ty.zigTypeTag(zcu)) {
.error_union => ty = ty.errorUnionPayload(zcu),
.optional => ty = ty.optionalChild(zcu),
.pointer => ty = if (ty.isSinglePointer(zcu)) ty.childType(zcu) else break,
.enum_literal, .error_set => {
// Treat this as a normal enum literal.
break :res Air.internedToRef(try pt.intern(.{ .enum_literal = name }));
Expand Down
32 changes: 31 additions & 1 deletion src/arch/riscv64/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3364,8 +3364,38 @@ fn airOptionalPayloadPtr(func: *Func, inst: Air.Inst.Index) !void {
}

fn airOptionalPayloadPtrSet(func: *Func, inst: Air.Inst.Index) !void {
const zcu = func.pt.zcu;

const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else return func.fail("TODO implement .optional_payload_ptr_set for {}", .{func.target.cpu.arch});
const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
const dst_ty = func.typeOfIndex(inst);
const src_ty = func.typeOf(ty_op.operand);
const opt_ty = src_ty.childType(zcu);
const src_mcv = try func.resolveInst(ty_op.operand);

if (opt_ty.optionalReprIsPayload(zcu)) {
break :result if (func.reuseOperand(inst, ty_op.operand, 0, src_mcv))
src_mcv
else
try func.copyToNewRegister(inst, src_mcv);
}

const dst_mcv: MCValue = if (src_mcv.isRegister() and
func.reuseOperand(inst, ty_op.operand, 0, src_mcv))
src_mcv
else
try func.copyToNewRegister(inst, src_mcv);

const pl_ty = dst_ty.childType(zcu);
const pl_abi_size: i32 = @intCast(pl_ty.abiSize(zcu));
try func.genSetMem(
.{ .reg = dst_mcv.getReg().? },
pl_abi_size,
Type.bool,
.{ .immediate = 1 },
);
break :result dst_mcv;
};
return func.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}

Expand Down
1 change: 0 additions & 1 deletion test/behavior/cast.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1875,7 +1875,6 @@ test "peer type resolution: vector and optional vector" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;

var a: ?@Vector(3, u32) = .{ 0, 1, 2 };
var b: @Vector(3, u32) = .{ 3, 4, 5 };
Expand Down
48 changes: 48 additions & 0 deletions test/behavior/decl_literals.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,54 @@ test "decl literal" {
try expect(val.x == 123);
}

test "decl literal with optional" {
const S = struct {
x: u32,
const foo: ?@This() = .{ .x = 123 };
};

const val: ?S = .foo;
try expect(val.?.x == 123);
}

test "decl literal with pointer" {
const S = struct {
x: u32,
const foo: *const @This() = &.{ .x = 123 };
};

const val: *const S = .foo;
try expect(val.x == 123);
}

test "call decl literal with optional" {
if (builtin.zig_backend == .stage2_sparc64 or
builtin.zig_backend == .stage2_arm or
builtin.zig_backend == .stage2_aarch64 or
builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
const S = struct {
x: u32,
fn init() ?@This() {
return .{ .x = 123 };
}
};

const val: ?S = .init();
try expect(val.?.x == 123);
}

test "call decl literal with pointer" {
const S = struct {
x: u32,
fn init() *const @This() {
return &.{ .x = 123 };
}
};

const val: *const S = .init();
try expect(val.x == 123);
}

test "call decl literal" {
const S = struct {
x: u32,
Expand Down
1 change: 0 additions & 1 deletion test/behavior/optional.zig
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,6 @@ test "coerce an anon struct literal to optional struct" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;

const S = struct {
const Struct = struct {
Expand Down
3 changes: 0 additions & 3 deletions test/behavior/struct.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1165,7 +1165,6 @@ test "anon init through error unions and optionals" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;

const S = struct {
a: u32,
Expand Down Expand Up @@ -1193,7 +1192,6 @@ test "anon init through optional" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;

const S = struct {
a: u32,
Expand Down Expand Up @@ -1503,7 +1501,6 @@ test "no dependency loop on pointer to optional struct" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;

const S = struct {
const A = struct { b: B };
Expand Down
1 change: 0 additions & 1 deletion test/behavior/union.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1268,7 +1268,6 @@ test "extern union most-aligned field is smaller" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;

const U = extern union {
in6: extern struct {
Expand Down

0 comments on commit 4d81e8e

Please sign in to comment.