authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-24 22:27:54-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-24 22:28:37-07:00
log27eb42c15e4e9ab547eaf02cca8810cc0e10e6bf
tree83cd40198ef1f55946163766a04fe9202a510206
parentadb746a7017ba6f91974d5e940bc8a8f64bb45f5

Sema: implement tupleFieldVal, fix comptime elem_ptr


9 files changed, 90 insertions(+), 33 deletions(-)

src/Sema.zig+44
......@@ -14360,6 +14360,10 @@ fn structFieldVal(
1436014360 assert(unresolved_struct_ty.zigTypeTag() == .Struct);
1436114361
1436214362 const struct_ty = try sema.resolveTypeFields(block, src, unresolved_struct_ty);
14363 if (struct_ty.isTuple()) {
14364 return sema.tupleFieldVal(block, src, struct_byval, field_name, field_name_src, struct_ty);
14365 }
14366
1436314367 const struct_obj = struct_ty.castTag(.@"struct").?.data;
1436414368
1436514369 const field_index_usize = struct_obj.fields.getIndex(field_name) orelse
......@@ -14381,6 +14385,46 @@ fn structFieldVal(
1438114385 return block.addStructFieldVal(struct_byval, field_index, field.ty);
1438214386}
1438314387
14388fn tupleFieldVal(
14389 sema: *Sema,
14390 block: *Block,
14391 src: LazySrcLoc,
14392 tuple_byval: Air.Inst.Ref,
14393 field_name: []const u8,
14394 field_name_src: LazySrcLoc,
14395 tuple_ty: Type,
14396) CompileError!Air.Inst.Ref {
14397 const tuple = tuple_ty.castTag(.tuple).?.data;
14398
14399 if (mem.eql(u8, field_name, "len")) {
14400 return sema.addIntUnsigned(Type.usize, tuple.types.len);
14401 }
14402
14403 const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| {
14404 return sema.fail(block, field_name_src, "tuple {} has no such field '{s}': {s}", .{
14405 tuple_ty, field_name, @errorName(err),
14406 });
14407 };
14408
14409 const field_ty = tuple.types[field_index];
14410
14411 if (tuple.values[field_index].tag() != .unreachable_value) {
14412 return sema.addConstant(field_ty, tuple.values[field_index]);
14413 }
14414
14415 if (try sema.resolveMaybeUndefVal(block, src, tuple_byval)) |tuple_val| {
14416 if (tuple_val.isUndef()) return sema.addConstUndef(field_ty);
14417 if ((try sema.typeHasOnePossibleValue(block, src, field_ty))) |opv| {
14418 return sema.addConstant(field_ty, opv);
14419 }
14420 const field_values = tuple_val.castTag(.@"struct").?.data;
14421 return sema.addConstant(field_ty, field_values[field_index]);
14422 }
14423
14424 try sema.requireRuntimeBlock(block, src);
14425 return block.addStructFieldVal(tuple_byval, field_index, field_ty);
14426}
14427
1438414428fn unionFieldPtr(
1438514429 sema: *Sema,
1438614430 block: *Block,
src/value.zig+29-11
......@@ -1851,7 +1851,13 @@ pub const Value = extern union {
18511851
18521852 return eql(a_payload.ptr, b_payload.ptr, ptr_ty);
18531853 },
1854 .elem_ptr => @panic("TODO: Implement more pointer eql cases"),
1854 .elem_ptr => {
1855 const a_payload = a.castTag(.elem_ptr).?.data;
1856 const b_payload = b.castTag(.elem_ptr).?.data;
1857 if (a_payload.index != b_payload.index) return false;
1858
1859 return eql(a_payload.array_ptr, b_payload.array_ptr, ty);
1860 },
18551861 .field_ptr => {
18561862 const a_payload = a.castTag(.field_ptr).?.data;
18571863 const b_payload = b.castTag(.field_ptr).?.data;
......@@ -2327,21 +2333,33 @@ pub const Value = extern union {
23272333 }
23282334
23292335 /// Returns a pointer to the element value at the index.
2330 pub fn elemPtr(self: Value, allocator: Allocator, index: usize) !Value {
2331 switch (self.tag()) {
2336 pub fn elemPtr(val: Value, arena: Allocator, index: usize) Allocator.Error!Value {
2337 switch (val.tag()) {
23322338 .elem_ptr => {
2333 const elem_ptr = self.castTag(.elem_ptr).?.data;
2334 return Tag.elem_ptr.create(allocator, .{
2339 const elem_ptr = val.castTag(.elem_ptr).?.data;
2340 return Tag.elem_ptr.create(arena, .{
23352341 .array_ptr = elem_ptr.array_ptr,
23362342 .index = elem_ptr.index + index,
23372343 });
23382344 },
2339 .slice => return Tag.elem_ptr.create(allocator, .{
2340 .array_ptr = self.castTag(.slice).?.data.ptr,
2341 .index = index,
2342 }),
2343 else => return Tag.elem_ptr.create(allocator, .{
2344 .array_ptr = self,
2345 .slice => {
2346 const ptr_val = val.castTag(.slice).?.data.ptr;
2347 switch (ptr_val.tag()) {
2348 .elem_ptr => {
2349 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
2350 return Tag.elem_ptr.create(arena, .{
2351 .array_ptr = elem_ptr.array_ptr,
2352 .index = elem_ptr.index + index,
2353 });
2354 },
2355 else => return Tag.elem_ptr.create(arena, .{
2356 .array_ptr = ptr_val,
2357 .index = index,
2358 }),
2359 }
2360 },
2361 else => return Tag.elem_ptr.create(arena, .{
2362 .array_ptr = val,
23452363 .index = index,
23462364 }),
23472365 }
test/behavior/basic.zig+5-5
......@@ -691,8 +691,6 @@ test "string escapes" {
691691}
692692
693693test "explicit cast optional pointers" {
694 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
695
696694 const a: ?*i32 = undefined;
697695 const b: ?*f32 = @ptrCast(?*f32, a);
698696 _ = b;
......@@ -735,7 +733,6 @@ test "string concatenation" {
735733}
736734
737735test "thread local variable" {
738 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
739736 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
740737
741738 const S = struct {
......@@ -746,7 +743,11 @@ test "thread local variable" {
746743}
747744
748745test "result location is optional inside error union" {
749 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
746 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
747 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
748 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
749 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
750 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
750751
751752 const x = maybe(true) catch unreachable;
752753 try expect(x.? == 42);
......@@ -760,7 +761,6 @@ fn maybe(x: bool) anyerror!?u32 {
760761}
761762
762763test "pointer to thread local array" {
763 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
764764 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
765765
766766 const s = "Hello world";
test/behavior/defer.zig+3-1
......@@ -97,7 +97,9 @@ fn runSomeErrorDefers(x: bool) !bool {
9797}
9898
9999test "mixing normal and error defers" {
100 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
100 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
101 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
102 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
101103
102104 try expect(runSomeErrorDefers(true) catch unreachable);
103105 try expect(result[0] == 'c');
test/behavior/eval.zig+1-5
......@@ -553,8 +553,6 @@ var simple_struct = SimpleStruct{ .field = 1234 };
553553const bound_fn = simple_struct.method;
554554
555555test "ptr to local array argument at comptime" {
556 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
557
558556 comptime {
559557 var bytes: [10]u8 = undefined;
560558 modifySomeBytes(bytes[0..]);
......@@ -591,8 +589,6 @@ fn testCompTimeUIntComparisons(x: u32) void {
591589const hi1 = "hi";
592590const hi2 = hi1;
593591test "const global shares pointer with other same one" {
594 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
595
596592 try assertEqualPtrs(&hi1[0], &hi2[0]);
597593 comptime try expect(&hi1[0] == &hi2[0]);
598594}
......@@ -704,7 +700,7 @@ fn loopNTimes(comptime n: usize) void {
704700}
705701
706702test "variable inside inline loop that has different types on different iterations" {
707 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
703 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
708704
709705 try testVarInsideInlineLoop(.{ true, @as(u32, 42) });
710706}
test/behavior/optional.zig+3-1
......@@ -235,7 +235,9 @@ test "assigning to an unwrapped optional field in an inline loop" {
235235}
236236
237237test "coerce an anon struct literal to optional struct" {
238 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
238 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
239 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
240 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
239241
240242 const S = struct {
241243 const Struct = struct {
test/behavior/pointers.zig-2
......@@ -177,8 +177,6 @@ test "implicit cast error unions with non-optional to optional pointer" {
177177}
178178
179179test "compare equality of optional and non-optional pointer" {
180 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
181
182180 const a = @intToPtr(*const usize, 0x12345678);
183181 const b = @intToPtr(?*usize, 0x12345678);
184182 try expect(a == b);
test/behavior/slice.zig+2-1
......@@ -565,7 +565,8 @@ test "array concat of slices gives slice" {
565565}
566566
567567test "slice bounds in comptime concatenation" {
568 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
568 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
569 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
569570
570571 const bs = comptime blk: {
571572 const b = "........1........";
test/behavior/translate_c_macros.zig+3-7
......@@ -30,16 +30,12 @@ test "initializer list expression" {
3030}
3131
3232test "sizeof in macros" {
33 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
34
35 try expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF(u32));
36 try expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF2(u32));
33 try expect(@as(c_int, @sizeOf(u32)) == h.MY_SIZEOF(u32));
34 try expect(@as(c_int, @sizeOf(u32)) == h.MY_SIZEOF2(u32));
3735}
3836
3937test "reference to a struct type" {
40 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
41
42 try expectEqual(@sizeOf(h.struct_Foo), h.SIZE_OF_FOO);
38 try expect(@sizeOf(h.struct_Foo) == h.SIZE_OF_FOO);
4339}
4440
4541test "cast negative integer to pointer" {