| ... | @@ -4138,23 +4138,24 @@ test "bytesAsSlice preserves pointer attributes" { | ... | @@ -4138,23 +4138,24 @@ test "bytesAsSlice preserves pointer attributes" { |
| 4138 | try testing.expectEqual(in.alignment, out.alignment); | 4138 | try testing.expectEqual(in.alignment, out.alignment); |
| 4139 | } | 4139 | } |
| 4140 | | 4140 | |
| 4141 | fn SliceAsBytesReturnType(comptime sliceType: type) type { | 4141 | fn SliceAsBytesReturnType(comptime Slice: type) type { |
| 4142 | if (!trait.isSlice(sliceType) and !trait.isPtrTo(.Array)(sliceType)) { | 4142 | if (!trait.isSlice(Slice) and !trait.isPtrTo(.Array)(Slice)) { |
| 4143 | @compileError("expected []T or *[_]T, passed " ++ @typeName(sliceType)); | 4143 | @compileError("expected []T or *[_]T, passed " ++ @typeName(Slice)); |
| 4144 | } | 4144 | } |
| 4145 | | 4145 | |
| 4146 | return CopyPtrAttrs(sliceType, .Slice, u8); | 4146 | return CopyPtrAttrs(Slice, .Slice, u8); |
| 4147 | } | 4147 | } |
| 4148 | | 4148 | |
| 4149 | /// Given a slice, returns a slice of the underlying bytes, preserving pointer attributes. | 4149 | /// Given a slice, returns a slice of the underlying bytes, preserving pointer attributes. |
| 4150 | pub fn sliceAsBytes(slice: anytype) SliceAsBytesReturnType(@TypeOf(slice)) { | 4150 | pub fn sliceAsBytes(slice: anytype) SliceAsBytesReturnType(@TypeOf(slice)) { |
| 4151 | const Slice = @TypeOf(slice); | 4151 | const Slice = @TypeOf(slice); |
| 4152 | | 4152 | |
| | 4153 | // a slice of zero-bit values always occupies zero bytes |
| | 4154 | if (@sizeOf(meta.Elem(Slice)) == 0) return &[0]u8{}; |
| | 4155 | |
| 4153 | // let's not give an undefined pointer to @ptrCast | 4156 | // let's not give an undefined pointer to @ptrCast |
| 4154 | // it may be equal to zero and fail a null check | 4157 | // it may be equal to zero and fail a null check |
| 4155 | if (slice.len == 0 and comptime meta.sentinel(Slice) == null) { | 4158 | if (slice.len == 0 and comptime meta.sentinel(Slice) == null) return &[0]u8{}; |
| 4156 | return &[0]u8{}; | | |
| 4157 | } | | |
| 4158 | | 4159 | |
| 4159 | const cast_target = CopyPtrAttrs(Slice, .Many, u8); | 4160 | const cast_target = CopyPtrAttrs(Slice, .Many, u8); |
| 4160 | | 4161 | |
| ... | @@ -4177,6 +4178,12 @@ test "sliceAsBytes with sentinel slice" { | ... | @@ -4177,6 +4178,12 @@ test "sliceAsBytes with sentinel slice" { |
| 4177 | try testing.expect(bytes.len == 0); | 4178 | try testing.expect(bytes.len == 0); |
| 4178 | } | 4179 | } |
| 4179 | | 4180 | |
| | 4181 | test "sliceAsBytes with zero-bit element type" { |
| | 4182 | const lots_of_nothing = [1]void{{}} ** 10_000; |
| | 4183 | const bytes = sliceAsBytes(&lots_of_nothing); |
| | 4184 | try testing.expect(bytes.len == 0); |
| | 4185 | } |
| | 4186 | |
| 4180 | test "sliceAsBytes packed struct at runtime and comptime" { | 4187 | test "sliceAsBytes packed struct at runtime and comptime" { |
| 4181 | const Foo = packed struct { | 4188 | const Foo = packed struct { |
| 4182 | a: u4, | 4189 | a: u4, |