| author | |
| committer | |
| log | 4d81e8ee915c3e012131cf90ed87cc8c6a01a934 |
| tree | fbd395f71db31e55c5fa4094d095b919b10c053e |
| parent | 8ddce90e62e52244b7f6d1104bb39a55350f0a83 |
| parent | bc161430b0006386ae19c51cfc574b5d8f8fef6e |
| signature |
make decl literals work with single item pointers7 files changed, 80 insertions(+), 7 deletions(-)
src/Sema.zig+1| ... | ... | @@ -8996,6 +8996,7 @@ fn zirDeclLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index, do_coerce: b |
| 8996 | 8996 | while (true) switch (ty.zigTypeTag(zcu)) { |
| 8997 | 8997 | .error_union => ty = ty.errorUnionPayload(zcu), |
| 8998 | 8998 | .optional => ty = ty.optionalChild(zcu), |
| 8999 | .pointer => ty = if (ty.isSinglePointer(zcu)) ty.childType(zcu) else break, | |
| 8999 | 9000 | .enum_literal, .error_set => { |
| 9000 | 9001 | // Treat this as a normal enum literal. |
| 9001 | 9002 | break :res Air.internedToRef(try pt.intern(.{ .enum_literal = name })); |
src/arch/riscv64/CodeGen.zig+31-1| ... | ... | @@ -3364,8 +3364,38 @@ fn airOptionalPayloadPtr(func: *Func, inst: Air.Inst.Index) !void { |
| 3364 | 3364 | } |
| 3365 | 3365 | |
| 3366 | 3366 | fn airOptionalPayloadPtrSet(func: *Func, inst: Air.Inst.Index) !void { |
| 3367 | const zcu = func.pt.zcu; | |
| 3368 | ||
| 3367 | 3369 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3368 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else return func.fail("TODO implement .optional_payload_ptr_set for {}", .{func.target.cpu.arch}); | |
| 3370 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { | |
| 3371 | const dst_ty = func.typeOfIndex(inst); | |
| 3372 | const src_ty = func.typeOf(ty_op.operand); | |
| 3373 | const opt_ty = src_ty.childType(zcu); | |
| 3374 | const src_mcv = try func.resolveInst(ty_op.operand); | |
| 3375 | ||
| 3376 | if (opt_ty.optionalReprIsPayload(zcu)) { | |
| 3377 | break :result if (func.reuseOperand(inst, ty_op.operand, 0, src_mcv)) | |
| 3378 | src_mcv | |
| 3379 | else | |
| 3380 | try func.copyToNewRegister(inst, src_mcv); | |
| 3381 | } | |
| 3382 | ||
| 3383 | const dst_mcv: MCValue = if (src_mcv.isRegister() and | |
| 3384 | func.reuseOperand(inst, ty_op.operand, 0, src_mcv)) | |
| 3385 | src_mcv | |
| 3386 | else | |
| 3387 | try func.copyToNewRegister(inst, src_mcv); | |
| 3388 | ||
| 3389 | const pl_ty = dst_ty.childType(zcu); | |
| 3390 | const pl_abi_size: i32 = @intCast(pl_ty.abiSize(zcu)); | |
| 3391 | try func.genSetMem( | |
| 3392 | .{ .reg = dst_mcv.getReg().? }, | |
| 3393 | pl_abi_size, | |
| 3394 | Type.bool, | |
| 3395 | .{ .immediate = 1 }, | |
| 3396 | ); | |
| 3397 | break :result dst_mcv; | |
| 3398 | }; | |
| 3369 | 3399 | return func.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 3370 | 3400 | } |
| 3371 | 3401 |
test/behavior/cast.zig-1| ... | ... | @@ -1875,7 +1875,6 @@ test "peer type resolution: vector and optional vector" { |
| 1875 | 1875 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1876 | 1876 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1877 | 1877 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| 1878 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 1879 | 1878 | |
| 1880 | 1879 | var a: ?@Vector(3, u32) = .{ 0, 1, 2 }; |
| 1881 | 1880 | var b: @Vector(3, u32) = .{ 3, 4, 5 }; |
test/behavior/decl_literals.zig+48| ... | ... | @@ -12,6 +12,54 @@ test "decl literal" { |
| 12 | 12 | try expect(val.x == 123); |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | test "decl literal with optional" { | |
| 16 | const S = struct { | |
| 17 | x: u32, | |
| 18 | const foo: ?@This() = .{ .x = 123 }; | |
| 19 | }; | |
| 20 | ||
| 21 | const val: ?S = .foo; | |
| 22 | try expect(val.?.x == 123); | |
| 23 | } | |
| 24 | ||
| 25 | test "decl literal with pointer" { | |
| 26 | const S = struct { | |
| 27 | x: u32, | |
| 28 | const foo: *const @This() = &.{ .x = 123 }; | |
| 29 | }; | |
| 30 | ||
| 31 | const val: *const S = .foo; | |
| 32 | try expect(val.x == 123); | |
| 33 | } | |
| 34 | ||
| 35 | test "call decl literal with optional" { | |
| 36 | if (builtin.zig_backend == .stage2_sparc64 or | |
| 37 | builtin.zig_backend == .stage2_arm or | |
| 38 | builtin.zig_backend == .stage2_aarch64 or | |
| 39 | builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | |
| 40 | const S = struct { | |
| 41 | x: u32, | |
| 42 | fn init() ?@This() { | |
| 43 | return .{ .x = 123 }; | |
| 44 | } | |
| 45 | }; | |
| 46 | ||
| 47 | const val: ?S = .init(); | |
| 48 | try expect(val.?.x == 123); | |
| 49 | } | |
| 50 | ||
| 51 | test "call decl literal with pointer" { | |
| 52 | const S = struct { | |
| 53 | x: u32, | |
| 54 | fn init() *const @This() { | |
| 55 | return &.{ .x = 123 }; | |
| 56 | } | |
| 57 | }; | |
| 58 | ||
| 59 | const val: *const S = .init(); | |
| 60 | try expect(val.x == 123); | |
| 61 | } | |
| 62 | ||
| 15 | 63 | test "call decl literal" { |
| 16 | 64 | const S = struct { |
| 17 | 65 | x: u32, |
test/behavior/optional.zig-1| ... | ... | @@ -320,7 +320,6 @@ test "coerce an anon struct literal to optional struct" { |
| 320 | 320 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 321 | 321 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 322 | 322 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 323 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 324 | 323 | |
| 325 | 324 | const S = struct { |
| 326 | 325 | const Struct = struct { |
test/behavior/struct.zig-3| ... | ... | @@ -1165,7 +1165,6 @@ test "anon init through error unions and optionals" { |
| 1165 | 1165 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1166 | 1166 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1167 | 1167 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1168 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 1169 | 1168 | |
| 1170 | 1169 | const S = struct { |
| 1171 | 1170 | a: u32, |
| ... | ... | @@ -1193,7 +1192,6 @@ test "anon init through optional" { |
| 1193 | 1192 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1194 | 1193 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1195 | 1194 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1196 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 1197 | 1195 | |
| 1198 | 1196 | const S = struct { |
| 1199 | 1197 | a: u32, |
| ... | ... | @@ -1503,7 +1501,6 @@ test "no dependency loop on pointer to optional struct" { |
| 1503 | 1501 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1504 | 1502 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1505 | 1503 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1506 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 1507 | 1504 | |
| 1508 | 1505 | const S = struct { |
| 1509 | 1506 | const A = struct { b: B }; |
test/behavior/union.zig-1| ... | ... | @@ -1268,7 +1268,6 @@ test "extern union most-aligned field is smaller" { |
| 1268 | 1268 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1269 | 1269 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1270 | 1270 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1271 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 1272 | 1271 | |
| 1273 | 1272 | const U = extern union { |
| 1274 | 1273 | in6: extern struct { |