| author | |
| committer | |
| log | 61266d26212e89e97d285eb61416d625303704bc |
| tree | 3bd43c1574911633e5214b253c712f3d181a2d38 |
| parent | 7fa88cc0a678a3690b61054030f5597b623964a4 |
| signature |
5 files changed, 38 insertions(+), 45 deletions(-)
doc/langref.html.in+16-20| ... | ... | @@ -2093,8 +2093,9 @@ var foo: u8 align(4) = 100; |
| 2093 | 2093 | test "global variable alignment" { |
| 2094 | 2094 | assert(@TypeOf(&foo).alignment == 4); |
| 2095 | 2095 | assert(@TypeOf(&foo) == *align(4) u8); |
| 2096 | const slice = @as(*[1]u8, &foo)[0..]; | |
| 2097 | assert(@TypeOf(slice) == []align(4) u8); | |
| 2096 | const as_pointer_to_array: *[1]u8 = &foo; | |
| 2097 | const as_slice: []u8 = as_pointer_to_array; | |
| 2098 | assert(@TypeOf(as_slice) == []align(4) u8); | |
| 2098 | 2099 | } |
| 2099 | 2100 | |
| 2100 | 2101 | fn derp() align(@sizeOf(usize) * 2) i32 { return 1234; } |
| ... | ... | @@ -2187,7 +2188,8 @@ test "basic slices" { |
| 2187 | 2188 | // a slice is that the array's length is part of the type and known at |
| 2188 | 2189 | // compile-time, whereas the slice's length is known at runtime. |
| 2189 | 2190 | // Both can be accessed with the `len` field. |
| 2190 | const slice = array[0..array.len]; | |
| 2191 | var known_at_runtime_zero: usize = 0; | |
| 2192 | const slice = array[known_at_runtime_zero..array.len]; | |
| 2191 | 2193 | assert(&slice[0] == &array[0]); |
| 2192 | 2194 | assert(slice.len == array.len); |
| 2193 | 2195 | |
| ... | ... | @@ -2207,13 +2209,15 @@ test "basic slices" { |
| 2207 | 2209 | {#code_end#} |
| 2208 | 2210 | <p>This is one reason we prefer slices to pointers.</p> |
| 2209 | 2211 | {#code_begin|test|slices#} |
| 2210 | const assert = @import("std").debug.assert; | |
| 2211 | const mem = @import("std").mem; | |
| 2212 | const fmt = @import("std").fmt; | |
| 2212 | const std = @import("std"); | |
| 2213 | const assert = std.debug.assert; | |
| 2214 | const mem = std.mem; | |
| 2215 | const fmt = std.fmt; | |
| 2213 | 2216 | |
| 2214 | 2217 | test "using slices for strings" { |
| 2215 | // Zig has no concept of strings. String literals are arrays of u8, and | |
| 2216 | // in general the string type is []u8 (slice of u8). | |
| 2218 | // Zig has no concept of strings. String literals are const pointers to | |
| 2219 | // arrays of u8, and by convention parameters that are "strings" are | |
| 2220 | // expected to be UTF-8 encoded slices of u8. | |
| 2217 | 2221 | // Here we coerce [5]u8 to []const u8 |
| 2218 | 2222 | const hello: []const u8 = "hello"; |
| 2219 | 2223 | const world: []const u8 = "世界"; |
| ... | ... | @@ -2222,7 +2226,7 @@ test "using slices for strings" { |
| 2222 | 2226 | // You can use slice syntax on an array to convert an array into a slice. |
| 2223 | 2227 | const all_together_slice = all_together[0..]; |
| 2224 | 2228 | // String concatenation example. |
| 2225 | const hello_world = try fmt.bufPrint(all_together_slice, "{} {}", .{hello, world}); | |
| 2229 | const hello_world = try fmt.bufPrint(all_together_slice, "{} {}", .{ hello, world }); | |
| 2226 | 2230 | |
| 2227 | 2231 | // Generally, you can use UTF-8 and not worry about whether something is a |
| 2228 | 2232 | // string. If you don't need to deal with individual characters, no need |
| ... | ... | @@ -2239,23 +2243,15 @@ test "slice pointer" { |
| 2239 | 2243 | slice[2] = 3; |
| 2240 | 2244 | assert(slice[2] == 3); |
| 2241 | 2245 | // The slice is mutable because we sliced a mutable pointer. |
| 2242 | assert(@TypeOf(slice) == []u8); | |
| 2246 | // Furthermore, it is actually a pointer to an array, since the start | |
| 2247 | // and end indexes were both comptime-known. | |
| 2248 | assert(@TypeOf(slice) == *[5]u8); | |
| 2243 | 2249 | |
| 2244 | 2250 | // You can also slice a slice: |
| 2245 | 2251 | const slice2 = slice[2..3]; |
| 2246 | 2252 | assert(slice2.len == 1); |
| 2247 | 2253 | assert(slice2[0] == 3); |
| 2248 | 2254 | } |
| 2249 | ||
| 2250 | test "slice widening" { | |
| 2251 | // Zig supports slice widening and slice narrowing. Cast a slice of u8 | |
| 2252 | // to a slice of anything else, and Zig will perform the length conversion. | |
| 2253 | const array align(@alignOf(u32)) = [_]u8{ 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13 }; | |
| 2254 | const slice = mem.bytesAsSlice(u32, array[0..]); | |
| 2255 | assert(slice.len == 2); | |
| 2256 | assert(slice[0] == 0x12121212); | |
| 2257 | assert(slice[1] == 0x13131313); | |
| 2258 | } | |
| 2259 | 2255 | {#code_end#} |
| 2260 | 2256 | {#see_also|Pointers|for|Arrays#} |
| 2261 | 2257 |
lib/std/os/windows.zig+9-1| ... | ... | @@ -1276,7 +1276,15 @@ pub fn unexpectedError(err: Win32Error) std.os.UnexpectedError { |
| 1276 | 1276 | // 614 is the length of the longest windows error desciption |
| 1277 | 1277 | var buf_u16: [614]u16 = undefined; |
| 1278 | 1278 | var buf_u8: [614]u8 = undefined; |
| 1279 | var len = kernel32.FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, null, err, MAKELANGID(LANG.NEUTRAL, SUBLANG.DEFAULT), buf_u16[0..].ptr, buf_u16.len / @sizeOf(TCHAR), null); | |
| 1279 | const len = kernel32.FormatMessageW( | |
| 1280 | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, | |
| 1281 | null, | |
| 1282 | err, | |
| 1283 | MAKELANGID(LANG.NEUTRAL, SUBLANG.DEFAULT), | |
| 1284 | &buf_u16, | |
| 1285 | buf_u16.len / @sizeOf(TCHAR), | |
| 1286 | null, | |
| 1287 | ); | |
| 1280 | 1288 | _ = std.unicode.utf16leToUtf8(&buf_u8, buf_u16[0..len]) catch unreachable; |
| 1281 | 1289 | std.debug.warn("error.Unexpected: GetLastError({}): {}\n", .{ @enumToInt(err), buf_u8[0..len] }); |
| 1282 | 1290 | std.debug.dumpCurrentStackTrace(null); |
test/compare_output.zig+1-1| ... | ... | @@ -292,7 +292,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 292 | 292 | \\pub export fn main() c_int { |
| 293 | 293 | \\ var array = [_]u32{ 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 }; |
| 294 | 294 | \\ |
| 295 | \\ c.qsort(@ptrCast(?*c_void, array[0..].ptr), @intCast(c_ulong, array.len), @sizeOf(i32), compare_fn); | |
| 295 | \\ c.qsort(@ptrCast(?*c_void, &array), @intCast(c_ulong, array.len), @sizeOf(i32), compare_fn); | |
| 296 | 296 | \\ |
| 297 | 297 | \\ for (array) |item, i| { |
| 298 | 298 | \\ if (item != i) { |
test/compile_errors.zig+11-22| ... | ... | @@ -103,18 +103,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 103 | 103 | "tmp.zig:3:23: error: pointer to size 0 type has no address", |
| 104 | 104 | }); |
| 105 | 105 | |
| 106 | cases.addTest("slice to pointer conversion mismatch", | |
| 107 | \\pub fn bytesAsSlice(bytes: var) [*]align(1) const u16 { | |
| 108 | \\ return @ptrCast([*]align(1) const u16, bytes.ptr)[0..1]; | |
| 109 | \\} | |
| 110 | \\test "bytesAsSlice" { | |
| 111 | \\ const bytes = [_]u8{ 0xDE, 0xAD, 0xBE, 0xEF }; | |
| 112 | \\ const slice = bytesAsSlice(bytes[0..]); | |
| 113 | \\} | |
| 114 | , &[_][]const u8{ | |
| 115 | "tmp.zig:2:54: error: expected type '[*]align(1) const u16', found '[]align(1) const u16'", | |
| 116 | }); | |
| 117 | ||
| 118 | 106 | cases.addTest("access invalid @typeInfo decl", |
| 119 | 107 | \\const A = B; |
| 120 | 108 | \\test "Crash" { |
| ... | ... | @@ -1915,16 +1903,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 1915 | 1903 | "tmp.zig:7:15: error: switch must handle all possibilities", |
| 1916 | 1904 | }); |
| 1917 | 1905 | |
| 1918 | cases.add("reading past end of pointer casted array", | |
| 1919 | \\comptime { | |
| 1920 | \\ const array: [4]u8 = "aoeu".*; | |
| 1921 | \\ const slice = array[1..]; | |
| 1922 | \\ const int_ptr = @ptrCast(*const u24, slice.ptr); | |
| 1923 | \\ const deref = int_ptr.*; | |
| 1924 | \\} | |
| 1925 | , &[_][]const u8{ | |
| 1926 | "tmp.zig:5:26: error: attempt to read 4 bytes from [4]u8 at index 1 which is 3 bytes", | |
| 1927 | }); | |
| 1906 | // TODO uncomment before merging branch | |
| 1907 | //cases.add("reading past end of pointer casted array", | |
| 1908 | // \\comptime { | |
| 1909 | // \\ const array: [4]u8 = "aoeu".*; | |
| 1910 | // \\ const sub_array = array[1..]; | |
| 1911 | // \\ const int_ptr = @ptrCast(*const u24, sub_array); | |
| 1912 | // \\ const deref = int_ptr.*; | |
| 1913 | // \\} | |
| 1914 | //, &[_][]const u8{ | |
| 1915 | // "tmp.zig:5:26: error: attempt to read 4 bytes from [4]u8 at index 1 which is 3 bytes", | |
| 1916 | //}); | |
| 1928 | 1917 | |
| 1929 | 1918 | cases.add("error note for function parameter incompatibility", |
| 1930 | 1919 | \\fn do_the_thing(func: fn (arg: i32) void) void {} |
test/runtime_safety.zig+1-1| ... | ... | @@ -69,7 +69,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 69 | 69 | \\} |
| 70 | 70 | \\pub fn main() void { |
| 71 | 71 | \\ var buf: [4]u8 = undefined; |
| 72 | \\ const ptr = buf[0..].ptr; | |
| 72 | \\ const ptr: [*]u8 = &buf; | |
| 73 | 73 | \\ const slice = ptr[0..3 :0]; |
| 74 | 74 | \\} |
| 75 | 75 | ); |