authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-09-14 21:20:41+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-09-14 23:21:26+03:00
log29fd0c6d61d1569c1691fc5489d51311207b1759
tree8af5c37da1cec24b70f932d4a023d81a3ed56a50
parentd073836894df8b9fb56f24f577a51dd09a85a932
signaturelock-open Commit is signed but in an unrecognized format.

fix meta.cast behavior; add exhaustive tests


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

lib/std/meta.zig+24-12
...@@ -717,7 +717,7 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {...@@ -717,7 +717,7 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {
717 },717 },
718 .Optional => |opt| {718 .Optional => |opt| {
719 if (@typeInfo(opt.child) == .Pointer) {719 if (@typeInfo(opt.child) == .Pointer) {
720 return @ptrCast(DestType, @alignCast(dest_ptr, target));720 return @ptrCast(DestType, @alignCast(dest_ptr.alignment, target));
721 }721 }
722 },722 },
723 else => {},723 else => {},
...@@ -725,23 +725,24 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {...@@ -725,23 +725,24 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {
725 },725 },
726 .Optional => |dest_opt| {726 .Optional => |dest_opt| {
727 if (@typeInfo(dest_opt.child) == .Pointer) {727 if (@typeInfo(dest_opt.child) == .Pointer) {
728 const dest_ptr = @typeInfo(dest_opt.child).Pointer;
728 switch (@typeInfo(TargetType)) {729 switch (@typeInfo(TargetType)) {
729 .Int, .ComptimeInt => {730 .Int, .ComptimeInt => {
730 return @intToPtr(DestType, target);731 return @intToPtr(DestType, target);
731 },732 },
732 .Pointer => {733 .Pointer => {
733 return @ptrCast(DestType, @alignCast(@alignOf(dest_opt.child.Child), target));734 return @ptrCast(DestType, @alignCast(dest_ptr.alignment, target));
734 },735 },
735 .Optional => |target_opt| {736 .Optional => |target_opt| {
736 if (@typeInfo(target_opt.child) == .Pointer) {737 if (@typeInfo(target_opt.child) == .Pointer) {
737 return @ptrCast(DestType, @alignCast(@alignOf(dest_opt.child.Child), target));738 return @ptrCast(DestType, @alignCast(dest_ptr.alignment, target));
738 }739 }
739 },740 },
740 else => {},741 else => {},
741 }742 }
742 }743 }
743 },744 },
744 .Enum, .EnumLiteral => {745 .Enum => {
745 if (@typeInfo(TargetType) == .Int or @typeInfo(TargetType) == .ComptimeInt) {746 if (@typeInfo(TargetType) == .Int or @typeInfo(TargetType) == .ComptimeInt) {
746 return @intToEnum(DestType, target);747 return @intToEnum(DestType, target);
747 }748 }
...@@ -749,15 +750,18 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {...@@ -749,15 +750,18 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {
749 .Int, .ComptimeInt => {750 .Int, .ComptimeInt => {
750 switch (@typeInfo(TargetType)) {751 switch (@typeInfo(TargetType)) {
751 .Pointer => {752 .Pointer => {
752 return @as(DestType, @ptrToInt(target));753 return @intCast(DestType, @ptrToInt(target));
753 },754 },
754 .Optional => |opt| {755 .Optional => |opt| {
755 if (@typeInfo(opt.child) == .Pointer) {756 if (@typeInfo(opt.child) == .Pointer) {
756 return @as(DestType, @ptrToInt(target));757 return @intCast(DestType, @ptrToInt(target));
757 }758 }
758 },759 },
759 .Enum, .EnumLiteral => {760 .Enum => {
760 return @as(DestType, @enumToInt(target));761 return @intCast(DestType, @enumToInt(target));
762 },
763 .Int, .ComptimeInt => {
764 return @intCast(DestType, target);
761 },765 },
762 else => {},766 else => {},
763 }767 }
...@@ -776,10 +780,18 @@ test "std.meta.cast" {...@@ -776,10 +780,18 @@ test "std.meta.cast" {
776780
777 var i = @as(i64, 10);781 var i = @as(i64, 10);
778782
779 testing.expect(cast(?*c_void, 0) == @intToPtr(?*c_void, 0));
780 testing.expect(cast(*u8, 16) == @intToPtr(*u8, 16));783 testing.expect(cast(*u8, 16) == @intToPtr(*u8, 16));
781 testing.expect(cast(u64, @as(u32, 10)) == @as(u64, 10));
782 testing.expect(cast(E, 1) == .One);
783 testing.expect(cast(u8, E.Two) == 2);
784 testing.expect(cast(*u64, &i).* == @as(u64, 10));784 testing.expect(cast(*u64, &i).* == @as(u64, 10));
785 testing.expect(cast(*i64, @as(?*align(1) i64, &i)) == &i);
786
787 testing.expect(cast(?*u8, 2) == @intToPtr(*u8, 2));
788 testing.expect(cast(?*i64, @as(*align(1) i64, &i)) == &i);
789 testing.expect(cast(?*i64, @as(?*align(1) i64, &i)) == &i);
790
791 testing.expect(cast(E, 1) == .One);
792
793 testing.expectEqual(@as(u32, 4), cast(u32, @intToPtr(*u32, 4)));
794 testing.expectEqual(@as(u32, 4), cast(u32, @intToPtr(?*u32, 4)));
795 testing.expectEqual(@as(u32, 10), cast(u32, @as(u64, 10)));
796 testing.expectEqual(@as(u8, 2), cast(u8, E.Two));
785}797}