diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-02-24 22:27:54 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-02-24 22:28:37 -0700 |
| commit | 27eb42c15e4e9ab547eaf02cca8810cc0e10e6bf (patch) | |
| tree | 83cd40198ef1f55946163766a04fe9202a510206 | |
| parent | adb746a7017ba6f91974d5e940bc8a8f64bb45f5 (diff) | |
| download | zig-27eb42c15e4e9ab547eaf02cca8810cc0e10e6bf.tar.gz zig-27eb42c15e4e9ab547eaf02cca8810cc0e10e6bf.zip | |
Sema: implement tupleFieldVal, fix comptime elem_ptr
| -rw-r--r-- | src/Sema.zig | 44 | ||||
| -rw-r--r-- | src/value.zig | 40 | ||||
| -rw-r--r-- | test/behavior/basic.zig | 10 | ||||
| -rw-r--r-- | test/behavior/defer.zig | 4 | ||||
| -rw-r--r-- | test/behavior/eval.zig | 6 | ||||
| -rw-r--r-- | test/behavior/optional.zig | 4 | ||||
| -rw-r--r-- | test/behavior/pointers.zig | 2 | ||||
| -rw-r--r-- | test/behavior/slice.zig | 3 | ||||
| -rw-r--r-- | test/behavior/translate_c_macros.zig | 10 |
9 files changed, 90 insertions, 33 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 3ba9761cd8..ef9ba41bec 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -14360,6 +14360,10 @@ fn structFieldVal( assert(unresolved_struct_ty.zigTypeTag() == .Struct); const struct_ty = try sema.resolveTypeFields(block, src, unresolved_struct_ty); + if (struct_ty.isTuple()) { + return sema.tupleFieldVal(block, src, struct_byval, field_name, field_name_src, struct_ty); + } + const struct_obj = struct_ty.castTag(.@"struct").?.data; const field_index_usize = struct_obj.fields.getIndex(field_name) orelse @@ -14381,6 +14385,46 @@ fn structFieldVal( return block.addStructFieldVal(struct_byval, field_index, field.ty); } +fn tupleFieldVal( + sema: *Sema, + block: *Block, + src: LazySrcLoc, + tuple_byval: Air.Inst.Ref, + field_name: []const u8, + field_name_src: LazySrcLoc, + tuple_ty: Type, +) CompileError!Air.Inst.Ref { + const tuple = tuple_ty.castTag(.tuple).?.data; + + if (mem.eql(u8, field_name, "len")) { + return sema.addIntUnsigned(Type.usize, tuple.types.len); + } + + const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| { + return sema.fail(block, field_name_src, "tuple {} has no such field '{s}': {s}", .{ + tuple_ty, field_name, @errorName(err), + }); + }; + + const field_ty = tuple.types[field_index]; + + if (tuple.values[field_index].tag() != .unreachable_value) { + return sema.addConstant(field_ty, tuple.values[field_index]); + } + + if (try sema.resolveMaybeUndefVal(block, src, tuple_byval)) |tuple_val| { + if (tuple_val.isUndef()) return sema.addConstUndef(field_ty); + if ((try sema.typeHasOnePossibleValue(block, src, field_ty))) |opv| { + return sema.addConstant(field_ty, opv); + } + const field_values = tuple_val.castTag(.@"struct").?.data; + return sema.addConstant(field_ty, field_values[field_index]); + } + + try sema.requireRuntimeBlock(block, src); + return block.addStructFieldVal(tuple_byval, field_index, field_ty); +} + fn unionFieldPtr( sema: *Sema, block: *Block, diff --git a/src/value.zig b/src/value.zig index 0b3ad15469..4df36f79a1 100644 --- a/src/value.zig +++ b/src/value.zig @@ -1851,7 +1851,13 @@ pub const Value = extern union { return eql(a_payload.ptr, b_payload.ptr, ptr_ty); }, - .elem_ptr => @panic("TODO: Implement more pointer eql cases"), + .elem_ptr => { + const a_payload = a.castTag(.elem_ptr).?.data; + const b_payload = b.castTag(.elem_ptr).?.data; + if (a_payload.index != b_payload.index) return false; + + return eql(a_payload.array_ptr, b_payload.array_ptr, ty); + }, .field_ptr => { const a_payload = a.castTag(.field_ptr).?.data; const b_payload = b.castTag(.field_ptr).?.data; @@ -2327,21 +2333,33 @@ pub const Value = extern union { } /// Returns a pointer to the element value at the index. - pub fn elemPtr(self: Value, allocator: Allocator, index: usize) !Value { - switch (self.tag()) { + pub fn elemPtr(val: Value, arena: Allocator, index: usize) Allocator.Error!Value { + switch (val.tag()) { .elem_ptr => { - const elem_ptr = self.castTag(.elem_ptr).?.data; - return Tag.elem_ptr.create(allocator, .{ + const elem_ptr = val.castTag(.elem_ptr).?.data; + return Tag.elem_ptr.create(arena, .{ .array_ptr = elem_ptr.array_ptr, .index = elem_ptr.index + index, }); }, - .slice => return Tag.elem_ptr.create(allocator, .{ - .array_ptr = self.castTag(.slice).?.data.ptr, - .index = index, - }), - else => return Tag.elem_ptr.create(allocator, .{ - .array_ptr = self, + .slice => { + const ptr_val = val.castTag(.slice).?.data.ptr; + switch (ptr_val.tag()) { + .elem_ptr => { + const elem_ptr = ptr_val.castTag(.elem_ptr).?.data; + return Tag.elem_ptr.create(arena, .{ + .array_ptr = elem_ptr.array_ptr, + .index = elem_ptr.index + index, + }); + }, + else => return Tag.elem_ptr.create(arena, .{ + .array_ptr = ptr_val, + .index = index, + }), + } + }, + else => return Tag.elem_ptr.create(arena, .{ + .array_ptr = val, .index = index, }), } diff --git a/test/behavior/basic.zig b/test/behavior/basic.zig index 024e24e400..304b4a83f7 100644 --- a/test/behavior/basic.zig +++ b/test/behavior/basic.zig @@ -691,8 +691,6 @@ test "string escapes" { } test "explicit cast optional pointers" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO - const a: ?*i32 = undefined; const b: ?*f32 = @ptrCast(?*f32, a); _ = b; @@ -735,7 +733,6 @@ test "string concatenation" { } test "thread local variable" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO const S = struct { @@ -746,7 +743,11 @@ test "thread local variable" { } test "result location is optional inside error union" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const x = maybe(true) catch unreachable; try expect(x.? == 42); @@ -760,7 +761,6 @@ fn maybe(x: bool) anyerror!?u32 { } test "pointer to thread local array" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO const s = "Hello world"; diff --git a/test/behavior/defer.zig b/test/behavior/defer.zig index a9d363ddd1..360d6e14bb 100644 --- a/test/behavior/defer.zig +++ b/test/behavior/defer.zig @@ -97,7 +97,9 @@ fn runSomeErrorDefers(x: bool) !bool { } test "mixing normal and error defers" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO try expect(runSomeErrorDefers(true) catch unreachable); try expect(result[0] == 'c'); diff --git a/test/behavior/eval.zig b/test/behavior/eval.zig index 40e2377aea..a3313011a3 100644 --- a/test/behavior/eval.zig +++ b/test/behavior/eval.zig @@ -553,8 +553,6 @@ var simple_struct = SimpleStruct{ .field = 1234 }; const bound_fn = simple_struct.method; test "ptr to local array argument at comptime" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO - comptime { var bytes: [10]u8 = undefined; modifySomeBytes(bytes[0..]); @@ -591,8 +589,6 @@ fn testCompTimeUIntComparisons(x: u32) void { const hi1 = "hi"; const hi2 = hi1; test "const global shares pointer with other same one" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO - try assertEqualPtrs(&hi1[0], &hi2[0]); comptime try expect(&hi1[0] == &hi2[0]); } @@ -704,7 +700,7 @@ fn loopNTimes(comptime n: usize) void { } test "variable inside inline loop that has different types on different iterations" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO try testVarInsideInlineLoop(.{ true, @as(u32, 42) }); } diff --git a/test/behavior/optional.zig b/test/behavior/optional.zig index 33d3b6c268..fdef0cfa96 100644 --- a/test/behavior/optional.zig +++ b/test/behavior/optional.zig @@ -235,7 +235,9 @@ test "assigning to an unwrapped optional field in an inline loop" { } test "coerce an anon struct literal to optional struct" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { const Struct = struct { diff --git a/test/behavior/pointers.zig b/test/behavior/pointers.zig index 2832dd01d3..d3d2188b12 100644 --- a/test/behavior/pointers.zig +++ b/test/behavior/pointers.zig @@ -177,8 +177,6 @@ test "implicit cast error unions with non-optional to optional pointer" { } test "compare equality of optional and non-optional pointer" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO - const a = @intToPtr(*const usize, 0x12345678); const b = @intToPtr(?*usize, 0x12345678); try expect(a == b); diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index 01d132df54..e746535d97 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -565,7 +565,8 @@ test "array concat of slices gives slice" { } test "slice bounds in comptime concatenation" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const bs = comptime blk: { const b = "........1........"; diff --git a/test/behavior/translate_c_macros.zig b/test/behavior/translate_c_macros.zig index be66e75b9d..a67d315ffc 100644 --- a/test/behavior/translate_c_macros.zig +++ b/test/behavior/translate_c_macros.zig @@ -30,16 +30,12 @@ test "initializer list expression" { } test "sizeof in macros" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO - - try expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF(u32)); - try expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF2(u32)); + try expect(@as(c_int, @sizeOf(u32)) == h.MY_SIZEOF(u32)); + try expect(@as(c_int, @sizeOf(u32)) == h.MY_SIZEOF2(u32)); } test "reference to a struct type" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO - - try expectEqual(@sizeOf(h.struct_Foo), h.SIZE_OF_FOO); + try expect(@sizeOf(h.struct_Foo) == h.SIZE_OF_FOO); } test "cast negative integer to pointer" { |
