authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-24 18:08:10-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-24 18:09:45-07:00
log7cfa97aa4ee9eb49d97d7d3b88488387bf6d175f
tree58ec04014b5b46f15238237acc558ec2c56374ac
parent5c68afef94b0b80823e033bd6965fcda74e19ebe

std.meta.trait: remove assumption about vector ABI size

The unit test for hasUniqueRepresentation asserted that a vector of length 3 would not have a unique representation. This would be true if it were lowered to ABI size 8 instead of 6. However lowering it to ABI size 6 is perfectly valid depending on the target. This commit also simplifies the logic for hasUniqueRepresentation of integers.

1 files changed, 24 insertions(+), 26 deletions(-)

lib/std/meta/trait.zig+24-26
...@@ -18,7 +18,7 @@ pub fn multiTrait(comptime traits: anytype) TraitFn {...@@ -18,7 +18,7 @@ pub fn multiTrait(comptime traits: anytype) TraitFn {
18 return Closure.trait;18 return Closure.trait;
19}19}
2020
21test "std.meta.trait.multiTrait" {21test "multiTrait" {
22 const Vector2 = struct {22 const Vector2 = struct {
23 const MyType = @This();23 const MyType = @This();
2424
...@@ -54,7 +54,7 @@ pub fn hasFn(comptime name: []const u8) TraitFn {...@@ -54,7 +54,7 @@ pub fn hasFn(comptime name: []const u8) TraitFn {
54 return Closure.trait;54 return Closure.trait;
55}55}
5656
57test "std.meta.trait.hasFn" {57test "hasFn" {
58 const TestStruct = struct {58 const TestStruct = struct {
59 pub fn useless() void {}59 pub fn useless() void {}
60 };60 };
...@@ -84,7 +84,7 @@ pub fn hasField(comptime name: []const u8) TraitFn {...@@ -84,7 +84,7 @@ pub fn hasField(comptime name: []const u8) TraitFn {
84 return Closure.trait;84 return Closure.trait;
85}85}
8686
87test "std.meta.trait.hasField" {87test "hasField" {
88 const TestStruct = struct {88 const TestStruct = struct {
89 value: u32,89 value: u32,
90 };90 };
...@@ -105,7 +105,7 @@ pub fn is(comptime id: std.builtin.TypeId) TraitFn {...@@ -105,7 +105,7 @@ pub fn is(comptime id: std.builtin.TypeId) TraitFn {
105 return Closure.trait;105 return Closure.trait;
106}106}
107107
108test "std.meta.trait.is" {108test "is" {
109 try testing.expect(is(.Int)(u8));109 try testing.expect(is(.Int)(u8));
110 try testing.expect(!is(.Int)(f32));110 try testing.expect(!is(.Int)(f32));
111 try testing.expect(is(.Pointer)(*u8));111 try testing.expect(is(.Pointer)(*u8));
...@@ -123,7 +123,7 @@ pub fn isPtrTo(comptime id: std.builtin.TypeId) TraitFn {...@@ -123,7 +123,7 @@ pub fn isPtrTo(comptime id: std.builtin.TypeId) TraitFn {
123 return Closure.trait;123 return Closure.trait;
124}124}
125125
126test "std.meta.trait.isPtrTo" {126test "isPtrTo" {
127 try testing.expect(!isPtrTo(.Struct)(struct {}));127 try testing.expect(!isPtrTo(.Struct)(struct {}));
128 try testing.expect(isPtrTo(.Struct)(*struct {}));128 try testing.expect(isPtrTo(.Struct)(*struct {}));
129 try testing.expect(!isPtrTo(.Struct)(**struct {}));129 try testing.expect(!isPtrTo(.Struct)(**struct {}));
...@@ -139,7 +139,7 @@ pub fn isSliceOf(comptime id: std.builtin.TypeId) TraitFn {...@@ -139,7 +139,7 @@ pub fn isSliceOf(comptime id: std.builtin.TypeId) TraitFn {
139 return Closure.trait;139 return Closure.trait;
140}140}
141141
142test "std.meta.trait.isSliceOf" {142test "isSliceOf" {
143 try testing.expect(!isSliceOf(.Struct)(struct {}));143 try testing.expect(!isSliceOf(.Struct)(struct {}));
144 try testing.expect(isSliceOf(.Struct)([]struct {}));144 try testing.expect(isSliceOf(.Struct)([]struct {}));
145 try testing.expect(!isSliceOf(.Struct)([][]struct {}));145 try testing.expect(!isSliceOf(.Struct)([][]struct {}));
...@@ -159,7 +159,7 @@ pub fn isExtern(comptime T: type) bool {...@@ -159,7 +159,7 @@ pub fn isExtern(comptime T: type) bool {
159 };159 };
160}160}
161161
162test "std.meta.trait.isExtern" {162test "isExtern" {
163 const TestExStruct = extern struct {};163 const TestExStruct = extern struct {};
164 const TestStruct = struct {};164 const TestStruct = struct {};
165165
...@@ -177,7 +177,7 @@ pub fn isPacked(comptime T: type) bool {...@@ -177,7 +177,7 @@ pub fn isPacked(comptime T: type) bool {
177 };177 };
178}178}
179179
180test "std.meta.trait.isPacked" {180test "isPacked" {
181 const TestPStruct = packed struct {};181 const TestPStruct = packed struct {};
182 const TestStruct = struct {};182 const TestStruct = struct {};
183183
...@@ -222,7 +222,7 @@ pub fn isSingleItemPtr(comptime T: type) bool {...@@ -222,7 +222,7 @@ pub fn isSingleItemPtr(comptime T: type) bool {
222 return false;222 return false;
223}223}
224224
225test "std.meta.trait.isSingleItemPtr" {225test "isSingleItemPtr" {
226 const array = [_]u8{0} ** 10;226 const array = [_]u8{0} ** 10;
227 comptime try testing.expect(isSingleItemPtr(@TypeOf(&array[0])));227 comptime try testing.expect(isSingleItemPtr(@TypeOf(&array[0])));
228 comptime try testing.expect(!isSingleItemPtr(@TypeOf(array)));228 comptime try testing.expect(!isSingleItemPtr(@TypeOf(array)));
...@@ -237,7 +237,7 @@ pub fn isManyItemPtr(comptime T: type) bool {...@@ -237,7 +237,7 @@ pub fn isManyItemPtr(comptime T: type) bool {
237 return false;237 return false;
238}238}
239239
240test "std.meta.trait.isManyItemPtr" {240test "isManyItemPtr" {
241 const array = [_]u8{0} ** 10;241 const array = [_]u8{0} ** 10;
242 const mip = @ptrCast([*]const u8, &array[0]);242 const mip = @ptrCast([*]const u8, &array[0]);
243 try testing.expect(isManyItemPtr(@TypeOf(mip)));243 try testing.expect(isManyItemPtr(@TypeOf(mip)));
...@@ -252,7 +252,7 @@ pub fn isSlice(comptime T: type) bool {...@@ -252,7 +252,7 @@ pub fn isSlice(comptime T: type) bool {
252 return false;252 return false;
253}253}
254254
255test "std.meta.trait.isSlice" {255test "isSlice" {
256 const array = [_]u8{0} ** 10;256 const array = [_]u8{0} ** 10;
257 var runtime_zero: usize = 0;257 var runtime_zero: usize = 0;
258 try testing.expect(isSlice(@TypeOf(array[runtime_zero..])));258 try testing.expect(isSlice(@TypeOf(array[runtime_zero..])));
...@@ -270,7 +270,7 @@ pub fn isIndexable(comptime T: type) bool {...@@ -270,7 +270,7 @@ pub fn isIndexable(comptime T: type) bool {
270 return comptime is(.Array)(T) or is(.Vector)(T) or isTuple(T);270 return comptime is(.Array)(T) or is(.Vector)(T) or isTuple(T);
271}271}
272272
273test "std.meta.trait.isIndexable" {273test "isIndexable" {
274 const array = [_]u8{0} ** 10;274 const array = [_]u8{0} ** 10;
275 const slice = @as([]const u8, &array);275 const slice = @as([]const u8, &array);
276 const vector: meta.Vector(2, u32) = [_]u32{0} ** 2;276 const vector: meta.Vector(2, u32) = [_]u32{0} ** 2;
...@@ -291,7 +291,7 @@ pub fn isNumber(comptime T: type) bool {...@@ -291,7 +291,7 @@ pub fn isNumber(comptime T: type) bool {
291 };291 };
292}292}
293293
294test "std.meta.trait.isNumber" {294test "isNumber" {
295 const NotANumber = struct {295 const NotANumber = struct {
296 number: u8,296 number: u8,
297 };297 };
...@@ -342,7 +342,7 @@ pub fn isConstPtr(comptime T: type) bool {...@@ -342,7 +342,7 @@ pub fn isConstPtr(comptime T: type) bool {
342 return @typeInfo(T).Pointer.is_const;342 return @typeInfo(T).Pointer.is_const;
343}343}
344344
345test "std.meta.trait.isConstPtr" {345test "isConstPtr" {
346 var t = @as(u8, 0);346 var t = @as(u8, 0);
347 const c = @as(u8, 0);347 const c = @as(u8, 0);
348 try testing.expect(isConstPtr(*const @TypeOf(t)));348 try testing.expect(isConstPtr(*const @TypeOf(t)));
...@@ -358,7 +358,7 @@ pub fn isContainer(comptime T: type) bool {...@@ -358,7 +358,7 @@ pub fn isContainer(comptime T: type) bool {
358 };358 };
359}359}
360360
361test "std.meta.trait.isContainer" {361test "isContainer" {
362 const TestStruct = struct {};362 const TestStruct = struct {};
363 const TestUnion = union {363 const TestUnion = union {
364 a: void,364 a: void,
...@@ -380,7 +380,7 @@ pub fn isTuple(comptime T: type) bool {...@@ -380,7 +380,7 @@ pub fn isTuple(comptime T: type) bool {
380 return is(.Struct)(T) and @typeInfo(T).Struct.is_tuple;380 return is(.Struct)(T) and @typeInfo(T).Struct.is_tuple;
381}381}
382382
383test "std.meta.trait.isTuple" {383test "isTuple" {
384 const t1 = struct {};384 const t1 = struct {};
385 const t2 = .{ .a = 0 };385 const t2 = .{ .a = 0 };
386 const t3 = .{ 1, 2, 3 };386 const t3 = .{ 1, 2, 3 };
...@@ -429,7 +429,7 @@ pub fn isZigString(comptime T: type) bool {...@@ -429,7 +429,7 @@ pub fn isZigString(comptime T: type) bool {
429 }429 }
430}430}
431431
432test "std.meta.trait.isZigString" {432test "isZigString" {
433 try testing.expect(isZigString([]const u8));433 try testing.expect(isZigString([]const u8));
434 try testing.expect(isZigString([]u8));434 try testing.expect(isZigString([]u8));
435 try testing.expect(isZigString([:0]const u8));435 try testing.expect(isZigString([:0]const u8));
...@@ -475,7 +475,7 @@ pub fn hasDecls(comptime T: type, comptime names: anytype) bool {...@@ -475,7 +475,7 @@ pub fn hasDecls(comptime T: type, comptime names: anytype) bool {
475 return true;475 return true;
476}476}
477477
478test "std.meta.trait.hasDecls" {478test "hasDecls" {
479 const TestStruct1 = struct {};479 const TestStruct1 = struct {};
480 const TestStruct2 = struct {480 const TestStruct2 = struct {
481 pub var a: u32 = undefined;481 pub var a: u32 = undefined;
...@@ -501,7 +501,7 @@ pub fn hasFields(comptime T: type, comptime names: anytype) bool {...@@ -501,7 +501,7 @@ pub fn hasFields(comptime T: type, comptime names: anytype) bool {
501 return true;501 return true;
502}502}
503503
504test "std.meta.trait.hasFields" {504test "hasFields" {
505 const TestStruct1 = struct {};505 const TestStruct1 = struct {};
506 const TestStruct2 = struct {506 const TestStruct2 = struct {
507 a: u32,507 a: u32,
...@@ -527,7 +527,7 @@ pub fn hasFunctions(comptime T: type, comptime names: anytype) bool {...@@ -527,7 +527,7 @@ pub fn hasFunctions(comptime T: type, comptime names: anytype) bool {
527 return true;527 return true;
528}528}
529529
530test "std.meta.trait.hasFunctions" {530test "hasFunctions" {
531 const TestStruct1 = struct {};531 const TestStruct1 = struct {};
532 const TestStruct2 = struct {532 const TestStruct2 = struct {
533 pub fn a() void {}533 pub fn a() void {}
...@@ -557,9 +557,7 @@ pub fn hasUniqueRepresentation(comptime T: type) bool {...@@ -557,9 +557,7 @@ pub fn hasUniqueRepresentation(comptime T: type) bool {
557557
558 .Bool => return false,558 .Bool => return false,
559559
560 // The padding bits are undefined.560 .Int => |info| return @sizeOf(T) * 8 == info.bits,
561 .Int => |info| return (info.bits % 8) == 0 and
562 (info.bits == 0 or std.math.isPowerOfTwo(info.bits)),
563561
564 .Pointer => |info| return info.size != .Slice,562 .Pointer => |info| return info.size != .Slice,
565563
...@@ -577,11 +575,12 @@ pub fn hasUniqueRepresentation(comptime T: type) bool {...@@ -577,11 +575,12 @@ pub fn hasUniqueRepresentation(comptime T: type) bool {
577 return @sizeOf(T) == sum_size;575 return @sizeOf(T) == sum_size;
578 },576 },
579577
580 .Vector => |info| return comptime hasUniqueRepresentation(info.child) and @sizeOf(T) == @sizeOf(info.child) * info.len,578 .Vector => |info| return comptime hasUniqueRepresentation(info.child) and
579 @sizeOf(T) == @sizeOf(info.child) * info.len,
581 }580 }
582}581}
583582
584test "std.meta.trait.hasUniqueRepresentation" {583test "hasUniqueRepresentation" {
585 const TestStruct1 = struct {584 const TestStruct1 = struct {
586 a: u32,585 a: u32,
587 b: u32,586 b: u32,
...@@ -650,5 +649,4 @@ test "std.meta.trait.hasUniqueRepresentation" {...@@ -650,5 +649,4 @@ test "std.meta.trait.hasUniqueRepresentation" {
650 try testing.expect(!hasUniqueRepresentation([]const u8));649 try testing.expect(!hasUniqueRepresentation([]const u8));
651650
652 try testing.expect(hasUniqueRepresentation(@Vector(4, u16)));651 try testing.expect(hasUniqueRepresentation(@Vector(4, u16)));
653 try testing.expect(!hasUniqueRepresentation(@Vector(3, u16)));
654}652}