Commit 29fd0c6d61

Vexu <git@vexu.eu>
2020-09-14 20:20:41
fix meta.cast behavior; add exhaustive tests
1 parent d073836
Changed files (1)
lib
lib/std/meta.zig
@@ -717,7 +717,7 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {
                 },
                 .Optional => |opt| {
                     if (@typeInfo(opt.child) == .Pointer) {
-                        return @ptrCast(DestType, @alignCast(dest_ptr, target));
+                        return @ptrCast(DestType, @alignCast(dest_ptr.alignment, target));
                     }
                 },
                 else => {},
@@ -725,23 +725,24 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {
         },
         .Optional => |dest_opt| {
             if (@typeInfo(dest_opt.child) == .Pointer) {
+                const dest_ptr = @typeInfo(dest_opt.child).Pointer;
                 switch (@typeInfo(TargetType)) {
                     .Int, .ComptimeInt => {
                         return @intToPtr(DestType, target);
                     },
                     .Pointer => {
-                        return @ptrCast(DestType, @alignCast(@alignOf(dest_opt.child.Child), target));
+                        return @ptrCast(DestType, @alignCast(dest_ptr.alignment, target));
                     },
                     .Optional => |target_opt| {
                         if (@typeInfo(target_opt.child) == .Pointer) {
-                            return @ptrCast(DestType, @alignCast(@alignOf(dest_opt.child.Child), target));
+                            return @ptrCast(DestType, @alignCast(dest_ptr.alignment, target));
                         }
                     },
                     else => {},
                 }
             }
         },
-        .Enum, .EnumLiteral => {
+        .Enum => {
             if (@typeInfo(TargetType) == .Int or @typeInfo(TargetType) == .ComptimeInt) {
                 return @intToEnum(DestType, target);
             }
@@ -749,15 +750,18 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {
         .Int, .ComptimeInt => {
             switch (@typeInfo(TargetType)) {
                 .Pointer => {
-                    return @as(DestType, @ptrToInt(target));
+                    return @intCast(DestType, @ptrToInt(target));
                 },
                 .Optional => |opt| {
                     if (@typeInfo(opt.child) == .Pointer) {
-                        return @as(DestType, @ptrToInt(target));
+                        return @intCast(DestType, @ptrToInt(target));
                     }
                 },
-                .Enum, .EnumLiteral => {
-                    return @as(DestType, @enumToInt(target));
+                .Enum => {
+                    return @intCast(DestType, @enumToInt(target));
+                },
+                .Int, .ComptimeInt => {
+                    return @intCast(DestType, target);
                 },
                 else => {},
             }
@@ -776,10 +780,18 @@ test "std.meta.cast" {
 
     var i = @as(i64, 10);
 
-    testing.expect(cast(?*c_void, 0) == @intToPtr(?*c_void, 0));
     testing.expect(cast(*u8, 16) == @intToPtr(*u8, 16));
-    testing.expect(cast(u64, @as(u32, 10)) == @as(u64, 10));
-    testing.expect(cast(E, 1) == .One);
-    testing.expect(cast(u8, E.Two) == 2);
     testing.expect(cast(*u64, &i).* == @as(u64, 10));
+    testing.expect(cast(*i64, @as(?*align(1) i64, &i)) == &i);
+
+    testing.expect(cast(?*u8, 2) == @intToPtr(*u8, 2));
+    testing.expect(cast(?*i64, @as(*align(1) i64, &i)) == &i);
+    testing.expect(cast(?*i64, @as(?*align(1) i64, &i)) == &i);
+
+    testing.expect(cast(E, 1) == .One);
+
+    testing.expectEqual(@as(u32, 4), cast(u32, @intToPtr(*u32, 4)));
+    testing.expectEqual(@as(u32, 4), cast(u32, @intToPtr(?*u32, 4)));
+    testing.expectEqual(@as(u32, 10), cast(u32, @as(u64, 10)));
+    testing.expectEqual(@as(u8, 2), cast(u8, E.Two));
 }