authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-25 23:29:02-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-26 00:36:12-07:00
log2c9a5e791ba17987061b057083c99158e85f17d1
tree5aaf5166a35a6ed909eecf0a916bacf69cad5ea9
parent178cd60a5ef590c3b94d607690fa773cf13b93ce

organize behavior tests

Every test that is moved in this commit has been checked to see if it is now passing.

22 files changed, 1899 insertions(+), 1713 deletions(-)

test/behavior.zig+2-12
...@@ -91,8 +91,9 @@ test {...@@ -91,8 +91,9 @@ test {
91 // Tests that pass for stage1 and the llvm backend.91 // Tests that pass for stage1 and the llvm backend.
92 _ = @import("behavior/array_llvm.zig");92 _ = @import("behavior/array_llvm.zig");
93 _ = @import("behavior/atomics.zig");93 _ = @import("behavior/atomics.zig");
94 _ = @import("behavior/basic_llvm.zig");94 _ = @import("behavior/bugs/1025.zig");
95 _ = @import("behavior/bugs/1741.zig");95 _ = @import("behavior/bugs/1741.zig");
96 _ = @import("behavior/bugs/1914.zig");
96 _ = @import("behavior/bugs/2578.zig");97 _ = @import("behavior/bugs/2578.zig");
97 _ = @import("behavior/bugs/3007.zig");98 _ = @import("behavior/bugs/3007.zig");
98 _ = @import("behavior/bugs/9584.zig");99 _ = @import("behavior/bugs/9584.zig");
...@@ -116,13 +117,11 @@ test {...@@ -116,13 +117,11 @@ test {
116117
117 if (builtin.zig_backend == .stage1) {118 if (builtin.zig_backend == .stage1) {
118 // Tests that only pass for the stage1 backend.119 // Tests that only pass for the stage1 backend.
119 _ = @import("behavior/align_stage1.zig");
120 if (builtin.os.tag != .wasi) {120 if (builtin.os.tag != .wasi) {
121 _ = @import("behavior/asm.zig");121 _ = @import("behavior/asm.zig");
122 _ = @import("behavior/async_fn.zig");122 _ = @import("behavior/async_fn.zig");
123 }123 }
124 _ = @import("behavior/await_struct.zig");124 _ = @import("behavior/await_struct.zig");
125 _ = @import("behavior/bitcast_stage1.zig");
126 _ = @import("behavior/bitreverse.zig");125 _ = @import("behavior/bitreverse.zig");
127 _ = @import("behavior/bugs/421.zig");126 _ = @import("behavior/bugs/421.zig");
128 _ = @import("behavior/bugs/529.zig");127 _ = @import("behavior/bugs/529.zig");
...@@ -130,14 +129,12 @@ test {...@@ -130,14 +129,12 @@ test {
130 _ = @import("behavior/bugs/726.zig");129 _ = @import("behavior/bugs/726.zig");
131 _ = @import("behavior/bugs/828.zig");130 _ = @import("behavior/bugs/828.zig");
132 _ = @import("behavior/bugs/920.zig");131 _ = @import("behavior/bugs/920.zig");
133 _ = @import("behavior/bugs/1025.zig");
134 _ = @import("behavior/bugs/1076.zig");132 _ = @import("behavior/bugs/1076.zig");
135 _ = @import("behavior/bugs/1120.zig");133 _ = @import("behavior/bugs/1120.zig");
136 _ = @import("behavior/bugs/1421.zig");134 _ = @import("behavior/bugs/1421.zig");
137 _ = @import("behavior/bugs/1442.zig");135 _ = @import("behavior/bugs/1442.zig");
138 _ = @import("behavior/bugs/1607.zig");136 _ = @import("behavior/bugs/1607.zig");
139 _ = @import("behavior/bugs/1851.zig");137 _ = @import("behavior/bugs/1851.zig");
140 _ = @import("behavior/bugs/1914.zig");
141 _ = @import("behavior/bugs/2114.zig");138 _ = @import("behavior/bugs/2114.zig");
142 _ = @import("behavior/bugs/3384.zig");139 _ = @import("behavior/bugs/3384.zig");
143 _ = @import("behavior/bugs/3742.zig");140 _ = @import("behavior/bugs/3742.zig");
...@@ -155,18 +152,11 @@ test {...@@ -155,18 +152,11 @@ test {
155 _ = @import("behavior/bugs/10147.zig");152 _ = @import("behavior/bugs/10147.zig");
156 _ = @import("behavior/byteswap.zig");153 _ = @import("behavior/byteswap.zig");
157 _ = @import("behavior/call_stage1.zig");154 _ = @import("behavior/call_stage1.zig");
158 _ = @import("behavior/cast_stage1.zig");
159 _ = @import("behavior/const_slice_child.zig");155 _ = @import("behavior/const_slice_child.zig");
160 _ = @import("behavior/defer_stage1.zig");
161 _ = @import("behavior/enum_stage1.zig");
162 _ = @import("behavior/error_stage1.zig");156 _ = @import("behavior/error_stage1.zig");
163 _ = @import("behavior/eval_stage1.zig");
164 _ = @import("behavior/field_parent_ptr.zig");157 _ = @import("behavior/field_parent_ptr.zig");
165 _ = @import("behavior/floatop_stage1.zig");158 _ = @import("behavior/floatop_stage1.zig");
166 _ = @import("behavior/fn_stage1.zig");
167 _ = @import("behavior/fn_delegation.zig");159 _ = @import("behavior/fn_delegation.zig");
168 _ = @import("behavior/for_stage1.zig");
169 _ = @import("behavior/if_stage1.zig");
170 _ = @import("behavior/ir_block_deps.zig");160 _ = @import("behavior/ir_block_deps.zig");
171 _ = @import("behavior/math_stage1.zig");161 _ = @import("behavior/math_stage1.zig");
172 _ = @import("behavior/misc.zig");162 _ = @import("behavior/misc.zig");
test/behavior/align.zig+226
...@@ -204,3 +204,229 @@ test "function alignment" {...@@ -204,3 +204,229 @@ test "function alignment" {
204 noop1();204 noop1();
205 noop4();205 noop4();
206}206}
207
208test "implicitly decreasing fn alignment" {
209 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
210 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
211 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
212 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
213 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
214 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
215
216 // function alignment is a compile error on wasm32/wasm64
217 if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest;
218
219 try testImplicitlyDecreaseFnAlign(alignedSmall, 1234);
220 try testImplicitlyDecreaseFnAlign(alignedBig, 5678);
221}
222
223// TODO make it a compile error to put align on the fn proto instead of on the ptr
224fn testImplicitlyDecreaseFnAlign(ptr: *align(1) const fn () i32, answer: i32) !void {
225 try expect(ptr() == answer);
226}
227
228fn alignedSmall() align(8) i32 {
229 return 1234;
230}
231fn alignedBig() align(16) i32 {
232 return 5678;
233}
234
235test "@alignCast functions" {
236 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
237 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
238 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
239 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
240 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
241
242 // function alignment is a compile error on wasm32/wasm64
243 if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest;
244 if (native_arch == .thumb) return error.SkipZigTest;
245
246 try expect(fnExpectsOnly1(simple4) == 0x19);
247}
248fn fnExpectsOnly1(ptr: *const fn () align(1) i32) i32 {
249 return fnExpects4(@alignCast(4, ptr));
250}
251fn fnExpects4(ptr: *align(4) const fn () i32) i32 {
252 return ptr();
253}
254fn simple4() align(4) i32 {
255 return 0x19;
256}
257
258test "generic function with align param" {
259 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
260 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
261 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
262 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
263 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
264
265 // function alignment is a compile error on wasm32/wasm64
266 if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest;
267 if (native_arch == .thumb) return error.SkipZigTest;
268
269 try expect(whyWouldYouEverDoThis(1) == 0x1);
270 try expect(whyWouldYouEverDoThis(4) == 0x1);
271 try expect(whyWouldYouEverDoThis(8) == 0x1);
272}
273
274fn whyWouldYouEverDoThis(comptime align_bytes: u8) align(align_bytes) u8 {
275 _ = align_bytes;
276 return 0x1;
277}
278
279test "runtime known array index has best alignment possible" {
280 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
281 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
282 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
283
284 // take full advantage of over-alignment
285 var array align(4) = [_]u8{ 1, 2, 3, 4 };
286 try expect(@TypeOf(&array[0]) == *align(4) u8);
287 try expect(@TypeOf(&array[1]) == *u8);
288 try expect(@TypeOf(&array[2]) == *align(2) u8);
289 try expect(@TypeOf(&array[3]) == *u8);
290
291 // because align is too small but we still figure out to use 2
292 var bigger align(2) = [_]u64{ 1, 2, 3, 4 };
293 try expect(@TypeOf(&bigger[0]) == *align(2) u64);
294 try expect(@TypeOf(&bigger[1]) == *align(2) u64);
295 try expect(@TypeOf(&bigger[2]) == *align(2) u64);
296 try expect(@TypeOf(&bigger[3]) == *align(2) u64);
297
298 // because pointer is align 2 and u32 align % 2 == 0 we can assume align 2
299 var smaller align(2) = [_]u32{ 1, 2, 3, 4 };
300 var runtime_zero: usize = 0;
301 comptime try expect(@TypeOf(smaller[runtime_zero..]) == []align(2) u32);
302 comptime try expect(@TypeOf(smaller[runtime_zero..].ptr) == [*]align(2) u32);
303 try testIndex(smaller[runtime_zero..].ptr, 0, *align(2) u32);
304 try testIndex(smaller[runtime_zero..].ptr, 1, *align(2) u32);
305 try testIndex(smaller[runtime_zero..].ptr, 2, *align(2) u32);
306 try testIndex(smaller[runtime_zero..].ptr, 3, *align(2) u32);
307
308 // has to use ABI alignment because index known at runtime only
309 try testIndex2(array[runtime_zero..].ptr, 0, *u8);
310 try testIndex2(array[runtime_zero..].ptr, 1, *u8);
311 try testIndex2(array[runtime_zero..].ptr, 2, *u8);
312 try testIndex2(array[runtime_zero..].ptr, 3, *u8);
313}
314fn testIndex(smaller: [*]align(2) u32, index: usize, comptime T: type) !void {
315 comptime try expect(@TypeOf(&smaller[index]) == T);
316}
317fn testIndex2(ptr: [*]align(4) u8, index: usize, comptime T: type) !void {
318 comptime try expect(@TypeOf(&ptr[index]) == T);
319}
320
321test "alignment of function with c calling convention" {
322 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
323
324 var runtime_nothing = &nothing;
325 const casted1 = @ptrCast(*const u8, runtime_nothing);
326 const casted2 = @ptrCast(*const fn () callconv(.C) void, casted1);
327 casted2();
328}
329
330fn nothing() callconv(.C) void {}
331
332const DefaultAligned = struct {
333 nevermind: u32,
334 badguy: i128,
335};
336
337test "read 128-bit field from default aligned struct in stack memory" {
338 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
339 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
340 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
341 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
342
343 var default_aligned = DefaultAligned{
344 .nevermind = 1,
345 .badguy = 12,
346 };
347 try expect((@ptrToInt(&default_aligned.badguy) % 16) == 0);
348 try expect(12 == default_aligned.badguy);
349}
350
351var default_aligned_global = DefaultAligned{
352 .nevermind = 1,
353 .badguy = 12,
354};
355
356test "read 128-bit field from default aligned struct in global memory" {
357 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
358 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
359 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
360 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
361 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
362
363 try expect((@ptrToInt(&default_aligned_global.badguy) % 16) == 0);
364 try expect(12 == default_aligned_global.badguy);
365}
366
367test "struct field explicit alignment" {
368 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
369 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
370 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
371 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
372 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
373
374 const S = struct {
375 const Node = struct {
376 next: *Node,
377 massive_byte: u8 align(64),
378 };
379 };
380
381 var node: S.Node = undefined;
382 node.massive_byte = 100;
383 try expect(node.massive_byte == 100);
384 comptime try expect(@TypeOf(&node.massive_byte) == *align(64) u8);
385 try expect(@ptrToInt(&node.massive_byte) % 64 == 0);
386}
387
388test "align(@alignOf(T)) T does not force resolution of T" {
389 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
390 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
391 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
392 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
393 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
394
395 const S = struct {
396 const A = struct {
397 a: *align(@alignOf(A)) A,
398 };
399 fn doTheTest() void {
400 suspend {
401 resume @frame();
402 }
403 _ = bar(@Frame(doTheTest));
404 }
405 fn bar(comptime T: type) *align(@alignOf(T)) T {
406 ok = true;
407 return undefined;
408 }
409
410 var ok = false;
411 };
412 _ = async S.doTheTest();
413 try expect(S.ok);
414}
415
416test "align(N) on functions" {
417 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
418 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
419 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
420 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
421 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
422 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
423
424 // function alignment is a compile error on wasm32/wasm64
425 if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest;
426 if (native_arch == .thumb) return error.SkipZigTest;
427
428 try expect((@ptrToInt(&overaligned_fn) & (0x1000 - 1)) == 0);
429}
430fn overaligned_fn() align(0x1000) i32 {
431 return 42;
432}
test/behavior/align_stage1.zig deleted-174
...@@ -1,174 +0,0 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const builtin = @import("builtin");
4const native_arch = builtin.target.cpu.arch;
5
6test "implicitly decreasing fn alignment" {
7 // function alignment is a compile error on wasm32/wasm64
8 if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest;
9
10 try testImplicitlyDecreaseFnAlign(alignedSmall, 1234);
11 try testImplicitlyDecreaseFnAlign(alignedBig, 5678);
12}
13
14fn testImplicitlyDecreaseFnAlign(ptr: fn () align(1) i32, answer: i32) !void {
15 try expect(ptr() == answer);
16}
17
18fn alignedSmall() align(8) i32 {
19 return 1234;
20}
21fn alignedBig() align(16) i32 {
22 return 5678;
23}
24
25test "@alignCast functions" {
26 // function alignment is a compile error on wasm32/wasm64
27 if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest;
28 if (native_arch == .thumb) return error.SkipZigTest;
29
30 try expect(fnExpectsOnly1(simple4) == 0x19);
31}
32fn fnExpectsOnly1(ptr: fn () align(1) i32) i32 {
33 return fnExpects4(@alignCast(4, ptr));
34}
35fn fnExpects4(ptr: fn () align(4) i32) i32 {
36 return ptr();
37}
38fn simple4() align(4) i32 {
39 return 0x19;
40}
41
42test "generic function with align param" {
43 // function alignment is a compile error on wasm32/wasm64
44 if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest;
45 if (native_arch == .thumb) return error.SkipZigTest;
46
47 try expect(whyWouldYouEverDoThis(1) == 0x1);
48 try expect(whyWouldYouEverDoThis(4) == 0x1);
49 try expect(whyWouldYouEverDoThis(8) == 0x1);
50}
51
52fn whyWouldYouEverDoThis(comptime align_bytes: u8) align(align_bytes) u8 {
53 _ = align_bytes;
54 return 0x1;
55}
56
57test "runtime known array index has best alignment possible" {
58 // take full advantage of over-alignment
59 var array align(4) = [_]u8{ 1, 2, 3, 4 };
60 try expect(@TypeOf(&array[0]) == *align(4) u8);
61 try expect(@TypeOf(&array[1]) == *u8);
62 try expect(@TypeOf(&array[2]) == *align(2) u8);
63 try expect(@TypeOf(&array[3]) == *u8);
64
65 // because align is too small but we still figure out to use 2
66 var bigger align(2) = [_]u64{ 1, 2, 3, 4 };
67 try expect(@TypeOf(&bigger[0]) == *align(2) u64);
68 try expect(@TypeOf(&bigger[1]) == *align(2) u64);
69 try expect(@TypeOf(&bigger[2]) == *align(2) u64);
70 try expect(@TypeOf(&bigger[3]) == *align(2) u64);
71
72 // because pointer is align 2 and u32 align % 2 == 0 we can assume align 2
73 var smaller align(2) = [_]u32{ 1, 2, 3, 4 };
74 var runtime_zero: usize = 0;
75 comptime try expect(@TypeOf(smaller[runtime_zero..]) == []align(2) u32);
76 comptime try expect(@TypeOf(smaller[runtime_zero..].ptr) == [*]align(2) u32);
77 try testIndex(smaller[runtime_zero..].ptr, 0, *align(2) u32);
78 try testIndex(smaller[runtime_zero..].ptr, 1, *align(2) u32);
79 try testIndex(smaller[runtime_zero..].ptr, 2, *align(2) u32);
80 try testIndex(smaller[runtime_zero..].ptr, 3, *align(2) u32);
81
82 // has to use ABI alignment because index known at runtime only
83 try testIndex2(array[runtime_zero..].ptr, 0, *u8);
84 try testIndex2(array[runtime_zero..].ptr, 1, *u8);
85 try testIndex2(array[runtime_zero..].ptr, 2, *u8);
86 try testIndex2(array[runtime_zero..].ptr, 3, *u8);
87}
88fn testIndex(smaller: [*]align(2) u32, index: usize, comptime T: type) !void {
89 comptime try expect(@TypeOf(&smaller[index]) == T);
90}
91fn testIndex2(ptr: [*]align(4) u8, index: usize, comptime T: type) !void {
92 comptime try expect(@TypeOf(&ptr[index]) == T);
93}
94
95test "alignment of function with c calling convention" {
96 var runtime_nothing = nothing;
97 const casted1 = @ptrCast(*const u8, runtime_nothing);
98 const casted2 = @ptrCast(fn () callconv(.C) void, casted1);
99 casted2();
100}
101
102fn nothing() callconv(.C) void {}
103
104const DefaultAligned = struct {
105 nevermind: u32,
106 badguy: i128,
107};
108
109test "read 128-bit field from default aligned struct in stack memory" {
110 var default_aligned = DefaultAligned{
111 .nevermind = 1,
112 .badguy = 12,
113 };
114 try expect((@ptrToInt(&default_aligned.badguy) % 16) == 0);
115 try expect(12 == default_aligned.badguy);
116}
117
118var default_aligned_global = DefaultAligned{
119 .nevermind = 1,
120 .badguy = 12,
121};
122
123test "read 128-bit field from default aligned struct in global memory" {
124 try expect((@ptrToInt(&default_aligned_global.badguy) % 16) == 0);
125 try expect(12 == default_aligned_global.badguy);
126}
127
128test "struct field explicit alignment" {
129 const S = struct {
130 const Node = struct {
131 next: *Node,
132 massive_byte: u8 align(64),
133 };
134 };
135
136 var node: S.Node = undefined;
137 node.massive_byte = 100;
138 try expect(node.massive_byte == 100);
139 comptime try expect(@TypeOf(&node.massive_byte) == *align(64) u8);
140 try expect(@ptrToInt(&node.massive_byte) % 64 == 0);
141}
142
143test "align(@alignOf(T)) T does not force resolution of T" {
144 const S = struct {
145 const A = struct {
146 a: *align(@alignOf(A)) A,
147 };
148 fn doTheTest() void {
149 suspend {
150 resume @frame();
151 }
152 _ = bar(@Frame(doTheTest));
153 }
154 fn bar(comptime T: type) *align(@alignOf(T)) T {
155 ok = true;
156 return undefined;
157 }
158
159 var ok = false;
160 };
161 _ = async S.doTheTest();
162 try expect(S.ok);
163}
164
165test "align(N) on functions" {
166 // function alignment is a compile error on wasm32/wasm64
167 if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest;
168 if (native_arch == .thumb) return error.SkipZigTest;
169
170 try expect((@ptrToInt(overaligned_fn) & (0x1000 - 1)) == 0);
171}
172fn overaligned_fn() align(0x1000) i32 {
173 return 42;
174}
test/behavior/basic.zig+399
...@@ -294,3 +294,402 @@ test "const ptr from var variable" {...@@ -294,3 +294,402 @@ test "const ptr from var variable" {
294fn copy(src: *const u64, dst: *u64) void {294fn copy(src: *const u64, dst: *u64) void {
295 dst.* = src.*;295 dst.* = src.*;
296}296}
297
298test "call result of if else expression" {
299 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
300 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
301
302 try expect(mem.eql(u8, f2(true), "a"));
303 try expect(mem.eql(u8, f2(false), "b"));
304}
305fn f2(x: bool) []const u8 {
306 return (if (x) fA else fB)();
307}
308
309test "memcpy and memset intrinsics" {
310 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
311
312 try testMemcpyMemset();
313 // TODO add comptime test coverage
314 //comptime try testMemcpyMemset();
315}
316
317fn testMemcpyMemset() !void {
318 var foo: [20]u8 = undefined;
319 var bar: [20]u8 = undefined;
320
321 @memset(&foo, 'A', foo.len);
322 @memcpy(&bar, &foo, bar.len);
323
324 try expect(bar[0] == 'A');
325 try expect(bar[11] == 'A');
326 try expect(bar[19] == 'A');
327}
328
329test "variable is allowed to be a pointer to an opaque type" {
330 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
331
332 var x: i32 = 1234;
333 _ = hereIsAnOpaqueType(@ptrCast(*OpaqueA, &x));
334}
335fn hereIsAnOpaqueType(ptr: *OpaqueA) *OpaqueA {
336 var a = ptr;
337 return a;
338}
339
340test "take address of parameter" {
341 try testTakeAddressOfParameter(12.34);
342}
343fn testTakeAddressOfParameter(f: f32) !void {
344 const f_ptr = &f;
345 try expect(f_ptr.* == 12.34);
346}
347
348test "pointer to void return type" {
349 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
350
351 try testPointerToVoidReturnType();
352}
353fn testPointerToVoidReturnType() anyerror!void {
354 const a = testPointerToVoidReturnType2();
355 return a.*;
356}
357const test_pointer_to_void_return_type_x = void{};
358fn testPointerToVoidReturnType2() *const void {
359 return &test_pointer_to_void_return_type_x;
360}
361
362test "array 2D const double ptr" {
363 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
364
365 const rect_2d_vertexes = [_][1]f32{
366 [_]f32{1.0},
367 [_]f32{2.0},
368 };
369 try testArray2DConstDoublePtr(&rect_2d_vertexes[0][0]);
370}
371
372fn testArray2DConstDoublePtr(ptr: *const f32) !void {
373 const ptr2 = @ptrCast([*]const f32, ptr);
374 try expect(ptr2[0] == 1.0);
375 try expect(ptr2[1] == 2.0);
376}
377
378test "double implicit cast in same expression" {
379 var x = @as(i32, @as(u16, nine()));
380 try expect(x == 9);
381}
382fn nine() u8 {
383 return 9;
384}
385
386test "struct inside function" {
387 try testStructInFn();
388 comptime try testStructInFn();
389}
390
391fn testStructInFn() !void {
392 const BlockKind = u32;
393
394 const Block = struct {
395 kind: BlockKind,
396 };
397
398 var block = Block{ .kind = 1234 };
399
400 block.kind += 1;
401
402 try expect(block.kind == 1235);
403}
404
405test "fn call returning scalar optional in equality expression" {
406 try expect(getNull() == null);
407}
408
409fn getNull() ?*i32 {
410 return null;
411}
412
413test "global variable assignment with optional unwrapping with var initialized to undefined" {
414 const S = struct {
415 var data: i32 = 1234;
416 fn foo() ?*i32 {
417 return &data;
418 }
419 };
420 global_foo = S.foo() orelse {
421 @panic("bad");
422 };
423 try expect(global_foo.* == 1234);
424}
425
426var global_foo: *i32 = undefined;
427
428test "peer result location with typed parent, runtime condition, comptime prongs" {
429 const S = struct {
430 fn doTheTest(arg: i32) i32 {
431 const st = Structy{
432 .bleh = if (arg == 1) 1 else 1,
433 };
434
435 if (st.bleh == 1)
436 return 1234;
437 return 0;
438 }
439
440 const Structy = struct {
441 bleh: i32,
442 };
443 };
444 try expect(S.doTheTest(0) == 1234);
445 try expect(S.doTheTest(1) == 1234);
446}
447
448test "non-ambiguous reference of shadowed decls" {
449 try expect(ZA().B().Self != ZA().Self);
450}
451
452fn ZA() type {
453 return struct {
454 b: B(),
455
456 const Self = @This();
457
458 fn B() type {
459 return struct {
460 const Self = @This();
461 };
462 }
463 };
464}
465
466test "use of declaration with same name as primitive" {
467 const S = struct {
468 const @"u8" = u16;
469 const alias = @"u8";
470 };
471 const a: S.u8 = 300;
472 try expect(a == 300);
473
474 const b: S.alias = 300;
475 try expect(b == 300);
476
477 const @"u8" = u16;
478 const c: @"u8" = 300;
479 try expect(c == 300);
480}
481
482test "constant equal function pointers" {
483 const alias = emptyFn;
484 try expect(comptime x: {
485 break :x emptyFn == alias;
486 });
487}
488
489fn emptyFn() void {}
490
491const addr1 = @ptrCast(*const u8, &emptyFn);
492test "comptime cast fn to ptr" {
493 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
494
495 const addr2 = @ptrCast(*const u8, &emptyFn);
496 comptime try expect(addr1 == addr2);
497}
498
499test "equality compare fn ptrs" {
500 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
501
502 var a = &emptyFn;
503 try expect(a == a);
504}
505
506test "self reference through fn ptr field" {
507 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
508 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
509
510 const S = struct {
511 const A = struct {
512 f: *const fn (A) u8,
513 };
514
515 fn foo(a: A) u8 {
516 _ = a;
517 return 12;
518 }
519 };
520 var a: S.A = undefined;
521 a.f = S.foo;
522 try expect(a.f(a) == 12);
523}
524
525test "global variable initialized to global variable array element" {
526 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
527
528 try expect(global_ptr == &gdt[0]);
529}
530const GDTEntry = struct {
531 field: i32,
532};
533var gdt = [_]GDTEntry{
534 GDTEntry{ .field = 1 },
535 GDTEntry{ .field = 2 },
536};
537var global_ptr = &gdt[0];
538
539test "global constant is loaded with a runtime-known index" {
540 const S = struct {
541 fn doTheTest() !void {
542 var index: usize = 1;
543 const ptr = &pieces[index].field;
544 try expect(ptr.* == 2);
545 }
546 const Piece = struct {
547 field: i32,
548 };
549 const pieces = [_]Piece{ Piece{ .field = 1 }, Piece{ .field = 2 }, Piece{ .field = 3 } };
550 };
551 try S.doTheTest();
552}
553
554test "multiline string literal is null terminated" {
555 const s1 =
556 \\one
557 \\two)
558 \\three
559 ;
560 const s2 = "one\ntwo)\nthree";
561 try expect(std.cstr.cmp(s1, s2) == 0);
562}
563
564test "string escapes" {
565 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
566
567 try expectEqualStrings("\"", "\x22");
568 try expectEqualStrings("\'", "\x27");
569 try expectEqualStrings("\n", "\x0a");
570 try expectEqualStrings("\r", "\x0d");
571 try expectEqualStrings("\t", "\x09");
572 try expectEqualStrings("\\", "\x5c");
573 try expectEqualStrings("\u{1234}\u{069}\u{1}", "\xe1\x88\xb4\x69\x01");
574}
575
576test "explicit cast optional pointers" {
577 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
578
579 const a: ?*i32 = undefined;
580 const b: ?*f32 = @ptrCast(?*f32, a);
581 _ = b;
582}
583
584test "pointer comparison" {
585 const a = @as([]const u8, "a");
586 const b = &a;
587 try expect(ptrEql(b, b));
588}
589fn ptrEql(a: *const []const u8, b: *const []const u8) bool {
590 return a == b;
591}
592
593test "string concatenation" {
594 const a = "OK" ++ " IT " ++ "WORKED";
595 const b = "OK IT WORKED";
596
597 comptime try expect(@TypeOf(a) == *const [12:0]u8);
598 comptime try expect(@TypeOf(b) == *const [12:0]u8);
599
600 const len = mem.len(b);
601 const len_with_null = len + 1;
602 {
603 var i: u32 = 0;
604 while (i < len_with_null) : (i += 1) {
605 try expect(a[i] == b[i]);
606 }
607 }
608 try expect(a[len] == 0);
609 try expect(b[len] == 0);
610}
611
612test "thread local variable" {
613 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
614
615 const S = struct {
616 threadlocal var t: i32 = 1234;
617 };
618 S.t += 1;
619 try expect(S.t == 1235);
620}
621
622test "result location is optional inside error union" {
623 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
624
625 const x = maybe(true) catch unreachable;
626 try expect(x.? == 42);
627}
628
629fn maybe(x: bool) anyerror!?u32 {
630 return switch (x) {
631 true => @as(u32, 42),
632 else => null,
633 };
634}
635
636test "pointer to thread local array" {
637 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
638
639 const s = "Hello world";
640 std.mem.copy(u8, buffer[0..], s);
641 try std.testing.expectEqualSlices(u8, buffer[0..], s);
642}
643
644threadlocal var buffer: [11]u8 = undefined;
645
646test "auto created variables have correct alignment" {
647 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
648
649 const S = struct {
650 fn foo(str: [*]const u8) u32 {
651 for (@ptrCast([*]align(1) const u32, str)[0..1]) |v| {
652 return v;
653 }
654 return 0;
655 }
656 };
657 try expect(S.foo("\x7a\x7a\x7a\x7a") == 0x7a7a7a7a);
658 comptime try expect(S.foo("\x7a\x7a\x7a\x7a") == 0x7a7a7a7a);
659}
660
661test "extern variable with non-pointer opaque type" {
662 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
663
664 @export(var_to_export, .{ .name = "opaque_extern_var" });
665 try expect(@ptrCast(*align(1) u32, &opaque_extern_var).* == 42);
666}
667extern var opaque_extern_var: opaque {};
668var var_to_export: u32 = 42;
669
670test "lazy typeInfo value as generic parameter" {
671 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
672
673 const S = struct {
674 fn foo(args: anytype) void {
675 _ = args;
676 }
677 };
678 S.foo(@typeInfo(@TypeOf(.{})));
679}
680
681test "variable name containing underscores does not shadow int primitive" {
682 const _u0 = 0;
683 const i_8 = 0;
684 const u16_ = 0;
685 const i3_2 = 0;
686 const u6__4 = 0;
687 const i2_04_8 = 0;
688
689 _ = _u0;
690 _ = i_8;
691 _ = u16_;
692 _ = i3_2;
693 _ = u6__4;
694 _ = i2_04_8;
695}
test/behavior/basic_llvm.zig deleted-250
...@@ -1,250 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const mem = std.mem;
4const expect = std.testing.expect;
5const expectEqualStrings = std.testing.expectEqualStrings;
6
7test "call result of if else expression" {
8 try expect(mem.eql(u8, f2(true), "a"));
9 try expect(mem.eql(u8, f2(false), "b"));
10}
11fn f2(x: bool) []const u8 {
12 return (if (x) fA else fB)();
13}
14fn fA() []const u8 {
15 return "a";
16}
17fn fB() []const u8 {
18 return "b";
19}
20
21test "memcpy and memset intrinsics" {
22 try testMemcpyMemset();
23 // TODO add comptime test coverage
24 //comptime try testMemcpyMemset();
25}
26
27fn testMemcpyMemset() !void {
28 var foo: [20]u8 = undefined;
29 var bar: [20]u8 = undefined;
30
31 @memset(&foo, 'A', foo.len);
32 @memcpy(&bar, &foo, bar.len);
33
34 try expect(bar[0] == 'A');
35 try expect(bar[11] == 'A');
36 try expect(bar[19] == 'A');
37}
38
39const OpaqueA = opaque {};
40const OpaqueB = opaque {};
41
42test "variable is allowed to be a pointer to an opaque type" {
43 var x: i32 = 1234;
44 _ = hereIsAnOpaqueType(@ptrCast(*OpaqueA, &x));
45}
46fn hereIsAnOpaqueType(ptr: *OpaqueA) *OpaqueA {
47 var a = ptr;
48 return a;
49}
50
51test "take address of parameter" {
52 try testTakeAddressOfParameter(12.34);
53}
54fn testTakeAddressOfParameter(f: f32) !void {
55 const f_ptr = &f;
56 try expect(f_ptr.* == 12.34);
57}
58
59test "pointer to void return type" {
60 try testPointerToVoidReturnType();
61}
62fn testPointerToVoidReturnType() anyerror!void {
63 const a = testPointerToVoidReturnType2();
64 return a.*;
65}
66const test_pointer_to_void_return_type_x = void{};
67fn testPointerToVoidReturnType2() *const void {
68 return &test_pointer_to_void_return_type_x;
69}
70
71test "array 2D const double ptr" {
72 const rect_2d_vertexes = [_][1]f32{
73 [_]f32{1.0},
74 [_]f32{2.0},
75 };
76 try testArray2DConstDoublePtr(&rect_2d_vertexes[0][0]);
77}
78
79fn testArray2DConstDoublePtr(ptr: *const f32) !void {
80 const ptr2 = @ptrCast([*]const f32, ptr);
81 try expect(ptr2[0] == 1.0);
82 try expect(ptr2[1] == 2.0);
83}
84
85test "double implicit cast in same expression" {
86 var x = @as(i32, @as(u16, nine()));
87 try expect(x == 9);
88}
89fn nine() u8 {
90 return 9;
91}
92
93test "struct inside function" {
94 try testStructInFn();
95 comptime try testStructInFn();
96}
97
98fn testStructInFn() !void {
99 const BlockKind = u32;
100
101 const Block = struct {
102 kind: BlockKind,
103 };
104
105 var block = Block{ .kind = 1234 };
106
107 block.kind += 1;
108
109 try expect(block.kind == 1235);
110}
111
112test "fn call returning scalar optional in equality expression" {
113 try expect(getNull() == null);
114}
115
116fn getNull() ?*i32 {
117 return null;
118}
119
120var global_foo: *i32 = undefined;
121
122test "global variable assignment with optional unwrapping with var initialized to undefined" {
123 const S = struct {
124 var data: i32 = 1234;
125 fn foo() ?*i32 {
126 return &data;
127 }
128 };
129 global_foo = S.foo() orelse {
130 @panic("bad");
131 };
132 try expect(global_foo.* == 1234);
133}
134
135test "peer result location with typed parent, runtime condition, comptime prongs" {
136 const S = struct {
137 fn doTheTest(arg: i32) i32 {
138 const st = Structy{
139 .bleh = if (arg == 1) 1 else 1,
140 };
141
142 if (st.bleh == 1)
143 return 1234;
144 return 0;
145 }
146
147 const Structy = struct {
148 bleh: i32,
149 };
150 };
151 try expect(S.doTheTest(0) == 1234);
152 try expect(S.doTheTest(1) == 1234);
153}
154
155fn ZA() type {
156 return struct {
157 b: B(),
158
159 const Self = @This();
160
161 fn B() type {
162 return struct {
163 const Self = @This();
164 };
165 }
166 };
167}
168test "non-ambiguous reference of shadowed decls" {
169 try expect(ZA().B().Self != ZA().Self);
170}
171
172test "use of declaration with same name as primitive" {
173 const S = struct {
174 const @"u8" = u16;
175 const alias = @"u8";
176 };
177 const a: S.u8 = 300;
178 try expect(a == 300);
179
180 const b: S.alias = 300;
181 try expect(b == 300);
182
183 const @"u8" = u16;
184 const c: @"u8" = 300;
185 try expect(c == 300);
186}
187
188fn emptyFn() void {}
189
190test "constant equal function pointers" {
191 const alias = emptyFn;
192 try expect(comptime x: {
193 break :x emptyFn == alias;
194 });
195}
196
197test "multiline string literal is null terminated" {
198 const s1 =
199 \\one
200 \\two)
201 \\three
202 ;
203 const s2 = "one\ntwo)\nthree";
204 try expect(std.cstr.cmp(s1, s2) == 0);
205}
206
207test "self reference through fn ptr field" {
208 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
209
210 const S = struct {
211 const A = struct {
212 f: *const fn (A) u8,
213 };
214
215 fn foo(a: A) u8 {
216 _ = a;
217 return 12;
218 }
219 };
220 var a: S.A = undefined;
221 a.f = S.foo;
222 try expect(a.f(a) == 12);
223}
224
225test "global variable initialized to global variable array element" {
226 try expect(global_ptr == &gdt[0]);
227}
228const GDTEntry = struct {
229 field: i32,
230};
231var gdt = [_]GDTEntry{
232 GDTEntry{ .field = 1 },
233 GDTEntry{ .field = 2 },
234};
235var global_ptr = &gdt[0];
236
237test "global constant is loaded with a runtime-known index" {
238 const S = struct {
239 fn doTheTest() !void {
240 var index: usize = 1;
241 const ptr = &pieces[index].field;
242 try expect(ptr.* == 2);
243 }
244 const Piece = struct {
245 field: i32,
246 };
247 const pieces = [_]Piece{ Piece{ .field = 1 }, Piece{ .field = 2 }, Piece{ .field = 3 } };
248 };
249 try S.doTheTest();
250}
test/behavior/bitcast.zig+163
...@@ -70,3 +70,166 @@ test "bitcast generates a temporary value" {...@@ -70,3 +70,166 @@ test "bitcast generates a temporary value" {
70 const x = @bitCast(u16, @bitCast([2]u8, y));70 const x = @bitCast(u16, @bitCast([2]u8, y));
71 try expect(y == x);71 try expect(y == x);
72}72}
73
74test "@bitCast packed structs at runtime and comptime" {
75 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
76 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
77 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
78 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
79 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
80
81 const Full = packed struct {
82 number: u16,
83 };
84 const Divided = packed struct {
85 half1: u8,
86 quarter3: u4,
87 quarter4: u4,
88 };
89 const S = struct {
90 fn doTheTest() !void {
91 var full = Full{ .number = 0x1234 };
92 var two_halves = @bitCast(Divided, full);
93 switch (native_endian) {
94 .Big => {
95 try expect(two_halves.half1 == 0x12);
96 try expect(two_halves.quarter3 == 0x3);
97 try expect(two_halves.quarter4 == 0x4);
98 },
99 .Little => {
100 try expect(two_halves.half1 == 0x34);
101 try expect(two_halves.quarter3 == 0x2);
102 try expect(two_halves.quarter4 == 0x1);
103 },
104 }
105 }
106 };
107 try S.doTheTest();
108 comptime try S.doTheTest();
109}
110
111test "@bitCast extern structs at runtime and comptime" {
112 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
113 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
114 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
115 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
116 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
117
118 const Full = extern struct {
119 number: u16,
120 };
121 const TwoHalves = extern struct {
122 half1: u8,
123 half2: u8,
124 };
125 const S = struct {
126 fn doTheTest() !void {
127 var full = Full{ .number = 0x1234 };
128 var two_halves = @bitCast(TwoHalves, full);
129 switch (native_endian) {
130 .Big => {
131 try expect(two_halves.half1 == 0x12);
132 try expect(two_halves.half2 == 0x34);
133 },
134 .Little => {
135 try expect(two_halves.half1 == 0x34);
136 try expect(two_halves.half2 == 0x12);
137 },
138 }
139 }
140 };
141 try S.doTheTest();
142 comptime try S.doTheTest();
143}
144
145test "bitcast packed struct to integer and back" {
146 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
147 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
148 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
149 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
150 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
151
152 const LevelUpMove = packed struct {
153 move_id: u9,
154 level: u7,
155 };
156 const S = struct {
157 fn doTheTest() !void {
158 var move = LevelUpMove{ .move_id = 1, .level = 2 };
159 var v = @bitCast(u16, move);
160 var back_to_a_move = @bitCast(LevelUpMove, v);
161 try expect(back_to_a_move.move_id == 1);
162 try expect(back_to_a_move.level == 2);
163 }
164 };
165 try S.doTheTest();
166 comptime try S.doTheTest();
167}
168
169test "implicit cast to error union by returning" {
170 const S = struct {
171 fn entry() !void {
172 try expect((func(-1) catch unreachable) == maxInt(u64));
173 }
174 pub fn func(sz: i64) anyerror!u64 {
175 return @bitCast(u64, sz);
176 }
177 };
178 try S.entry();
179 comptime try S.entry();
180}
181
182test "bitcast packed struct literal to byte" {
183 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
184 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
185 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
186 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
187 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
188
189 const Foo = packed struct {
190 value: u8,
191 };
192 const casted = @bitCast(u8, Foo{ .value = 0xF });
193 try expect(casted == 0xf);
194}
195
196test "comptime bitcast used in expression has the correct type" {
197 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
198 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
199 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
200 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
201 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
202
203 const Foo = packed struct {
204 value: u8,
205 };
206 try expect(@bitCast(u8, Foo{ .value = 0xF }) == 0xf);
207}
208
209test "bitcast passed as tuple element" {
210 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
211 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
212 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
213 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
214 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
215
216 const S = struct {
217 fn foo(args: anytype) !void {
218 comptime try expect(@TypeOf(args[0]) == f32);
219 try expect(args[0] == 12.34);
220 }
221 };
222 try S.foo(.{@bitCast(f32, @as(u32, 0x414570A4))});
223}
224
225test "triple level result location with bitcast sandwich passed as tuple element" {
226 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
227
228 const S = struct {
229 fn foo(args: anytype) !void {
230 comptime try expect(@TypeOf(args[0]) == f64);
231 try expect(args[0] > 12.33 and args[0] < 12.35);
232 }
233 };
234 try S.foo(.{@as(f64, @bitCast(f32, @as(u32, 0x414570A4)))});
235}
test/behavior/bitcast_stage1.zig deleted-131
...@@ -1,131 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const expect = std.testing.expect;
4const expectEqual = std.testing.expectEqual;
5const maxInt = std.math.maxInt;
6const native_endian = builtin.target.cpu.arch.endian();
7
8test "@bitCast packed structs at runtime and comptime" {
9 const Full = packed struct {
10 number: u16,
11 };
12 const Divided = packed struct {
13 half1: u8,
14 quarter3: u4,
15 quarter4: u4,
16 };
17 const S = struct {
18 fn doTheTest() !void {
19 var full = Full{ .number = 0x1234 };
20 var two_halves = @bitCast(Divided, full);
21 switch (native_endian) {
22 .Big => {
23 try expect(two_halves.half1 == 0x12);
24 try expect(two_halves.quarter3 == 0x3);
25 try expect(two_halves.quarter4 == 0x4);
26 },
27 .Little => {
28 try expect(two_halves.half1 == 0x34);
29 try expect(two_halves.quarter3 == 0x2);
30 try expect(two_halves.quarter4 == 0x1);
31 },
32 }
33 }
34 };
35 try S.doTheTest();
36 comptime try S.doTheTest();
37}
38
39test "@bitCast extern structs at runtime and comptime" {
40 const Full = extern struct {
41 number: u16,
42 };
43 const TwoHalves = extern struct {
44 half1: u8,
45 half2: u8,
46 };
47 const S = struct {
48 fn doTheTest() !void {
49 var full = Full{ .number = 0x1234 };
50 var two_halves = @bitCast(TwoHalves, full);
51 switch (native_endian) {
52 .Big => {
53 try expect(two_halves.half1 == 0x12);
54 try expect(two_halves.half2 == 0x34);
55 },
56 .Little => {
57 try expect(two_halves.half1 == 0x34);
58 try expect(two_halves.half2 == 0x12);
59 },
60 }
61 }
62 };
63 try S.doTheTest();
64 comptime try S.doTheTest();
65}
66
67test "bitcast packed struct to integer and back" {
68 const LevelUpMove = packed struct {
69 move_id: u9,
70 level: u7,
71 };
72 const S = struct {
73 fn doTheTest() !void {
74 var move = LevelUpMove{ .move_id = 1, .level = 2 };
75 var v = @bitCast(u16, move);
76 var back_to_a_move = @bitCast(LevelUpMove, v);
77 try expect(back_to_a_move.move_id == 1);
78 try expect(back_to_a_move.level == 2);
79 }
80 };
81 try S.doTheTest();
82 comptime try S.doTheTest();
83}
84
85test "implicit cast to error union by returning" {
86 const S = struct {
87 fn entry() !void {
88 try expect((func(-1) catch unreachable) == maxInt(u64));
89 }
90 pub fn func(sz: i64) anyerror!u64 {
91 return @bitCast(u64, sz);
92 }
93 };
94 try S.entry();
95 comptime try S.entry();
96}
97
98test "bitcast packed struct literal to byte" {
99 const Foo = packed struct {
100 value: u8,
101 };
102 const casted = @bitCast(u8, Foo{ .value = 0xF });
103 try expect(casted == 0xf);
104}
105
106test "comptime bitcast used in expression has the correct type" {
107 const Foo = packed struct {
108 value: u8,
109 };
110 try expect(@bitCast(u8, Foo{ .value = 0xF }) == 0xf);
111}
112
113test "bitcast passed as tuple element" {
114 const S = struct {
115 fn foo(args: anytype) !void {
116 comptime try expect(@TypeOf(args[0]) == f32);
117 try expect(args[0] == 12.34);
118 }
119 };
120 try S.foo(.{@bitCast(f32, @as(u32, 0x414570A4))});
121}
122
123test "triple level result location with bitcast sandwich passed as tuple element" {
124 const S = struct {
125 fn foo(args: anytype) !void {
126 comptime try expect(@TypeOf(args[0]) == f64);
127 try expect(args[0] > 12.33 and args[0] < 12.35);
128 }
129 };
130 try S.foo(.{@as(f64, @bitCast(f32, @as(u32, 0x414570A4)))});
131}
test/behavior/cast.zig+471
...@@ -336,3 +336,474 @@ test "expected [*c]const u8, found [*:0]const u8" {...@@ -336,3 +336,474 @@ test "expected [*c]const u8, found [*:0]const u8" {
336 var c: [*:0]const u8 = b;336 var c: [*:0]const u8 = b;
337 try expect(std.mem.eql(u8, c[0..5], "hello"));337 try expect(std.mem.eql(u8, c[0..5], "hello"));
338}338}
339
340test "explicit cast from integer to error type" {
341 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
342
343 try testCastIntToErr(error.ItBroke);
344 comptime try testCastIntToErr(error.ItBroke);
345}
346fn testCastIntToErr(err: anyerror) !void {
347 const x = @errorToInt(err);
348 const y = @intToError(x);
349 try expect(error.ItBroke == y);
350}
351
352test "peer resolve array and const slice" {
353 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
354
355 try testPeerResolveArrayConstSlice(true);
356 comptime try testPeerResolveArrayConstSlice(true);
357}
358fn testPeerResolveArrayConstSlice(b: bool) !void {
359 const value1 = if (b) "aoeu" else @as([]const u8, "zz");
360 const value2 = if (b) @as([]const u8, "zz") else "aoeu";
361 try expect(mem.eql(u8, value1, "aoeu"));
362 try expect(mem.eql(u8, value2, "zz"));
363}
364
365test "implicitly cast from T to anyerror!?T" {
366 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
367
368 try castToOptionalTypeError(1);
369 comptime try castToOptionalTypeError(1);
370}
371
372const A = struct {
373 a: i32,
374};
375fn castToOptionalTypeError(z: i32) !void {
376 const x = @as(i32, 1);
377 const y: anyerror!?i32 = x;
378 try expect((try y).? == 1);
379
380 const f = z;
381 const g: anyerror!?i32 = f;
382 _ = g catch {};
383
384 const a = A{ .a = z };
385 const b: anyerror!?A = a;
386 try expect((b catch unreachable).?.a == 1);
387}
388
389test "implicitly cast from [0]T to anyerror![]T" {
390 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
391 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
392 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
393
394 try testCastZeroArrayToErrSliceMut();
395 comptime try testCastZeroArrayToErrSliceMut();
396}
397
398fn testCastZeroArrayToErrSliceMut() !void {
399 try expect((gimmeErrOrSlice() catch unreachable).len == 0);
400}
401
402fn gimmeErrOrSlice() anyerror![]u8 {
403 return &[_]u8{};
404}
405
406test "peer type resolution: [0]u8, []const u8, and anyerror![]u8" {
407 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
408
409 const S = struct {
410 fn doTheTest() anyerror!void {
411 {
412 var data = "hi".*;
413 const slice = data[0..];
414 try expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0);
415 try expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
416 }
417 {
418 var data: [2]u8 = "hi".*;
419 const slice = data[0..];
420 try expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0);
421 try expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
422 }
423 }
424 };
425 try S.doTheTest();
426 comptime try S.doTheTest();
427}
428fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) anyerror![]u8 {
429 if (a) {
430 return &[_]u8{};
431 }
432
433 return slice[0..1];
434}
435
436test "implicit cast from *const [N]T to []const T" {
437 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
438
439 try testCastConstArrayRefToConstSlice();
440 comptime try testCastConstArrayRefToConstSlice();
441}
442
443fn testCastConstArrayRefToConstSlice() !void {
444 {
445 const blah = "aoeu".*;
446 const const_array_ref = &blah;
447 try expect(@TypeOf(const_array_ref) == *const [4:0]u8);
448 const slice: []const u8 = const_array_ref;
449 try expect(mem.eql(u8, slice, "aoeu"));
450 }
451 {
452 const blah: [4]u8 = "aoeu".*;
453 const const_array_ref = &blah;
454 try expect(@TypeOf(const_array_ref) == *const [4]u8);
455 const slice: []const u8 = const_array_ref;
456 try expect(mem.eql(u8, slice, "aoeu"));
457 }
458}
459
460test "peer type resolution: error and [N]T" {
461 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
462 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
463
464 try expect(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
465 comptime try expect(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
466 try expect(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));
467 comptime try expect(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));
468}
469
470fn testPeerErrorAndArray(x: u8) anyerror![]const u8 {
471 return switch (x) {
472 0x00 => "OK",
473 else => error.BadValue,
474 };
475}
476fn testPeerErrorAndArray2(x: u8) anyerror![]const u8 {
477 return switch (x) {
478 0x00 => "OK",
479 0x01 => "OKK",
480 else => error.BadValue,
481 };
482}
483
484test "single-item pointer of array to slice to unknown length pointer" {
485 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
486
487 try testCastPtrOfArrayToSliceAndPtr();
488 comptime try testCastPtrOfArrayToSliceAndPtr();
489}
490
491fn testCastPtrOfArrayToSliceAndPtr() !void {
492 {
493 var array = "aoeu".*;
494 const x: [*]u8 = &array;
495 x[0] += 1;
496 try expect(mem.eql(u8, array[0..], "boeu"));
497 const y: []u8 = &array;
498 y[0] += 1;
499 try expect(mem.eql(u8, array[0..], "coeu"));
500 }
501 {
502 var array: [4]u8 = "aoeu".*;
503 const x: [*]u8 = &array;
504 x[0] += 1;
505 try expect(mem.eql(u8, array[0..], "boeu"));
506 const y: []u8 = &array;
507 y[0] += 1;
508 try expect(mem.eql(u8, array[0..], "coeu"));
509 }
510}
511
512test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
513 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
514
515 const window_name = [1][*]const u8{"window name"};
516 const x: [*]const ?[*]const u8 = &window_name;
517 try expect(mem.eql(u8, std.mem.sliceTo(@ptrCast([*:0]const u8, x[0].?), 0), "window name"));
518}
519
520test "vector casts" {
521 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
522
523 const S = struct {
524 fn doTheTest() !void {
525 // Upcast (implicit, equivalent to @intCast)
526 var up0: @Vector(2, u8) = [_]u8{ 0x55, 0xaa };
527 var up1 = @as(@Vector(2, u16), up0);
528 var up2 = @as(@Vector(2, u32), up0);
529 var up3 = @as(@Vector(2, u64), up0);
530 // Downcast (safety-checked)
531 var down0 = up3;
532 var down1 = @intCast(@Vector(2, u32), down0);
533 var down2 = @intCast(@Vector(2, u16), down0);
534 var down3 = @intCast(@Vector(2, u8), down0);
535
536 try expect(mem.eql(u16, &@as([2]u16, up1), &[2]u16{ 0x55, 0xaa }));
537 try expect(mem.eql(u32, &@as([2]u32, up2), &[2]u32{ 0x55, 0xaa }));
538 try expect(mem.eql(u64, &@as([2]u64, up3), &[2]u64{ 0x55, 0xaa }));
539
540 try expect(mem.eql(u32, &@as([2]u32, down1), &[2]u32{ 0x55, 0xaa }));
541 try expect(mem.eql(u16, &@as([2]u16, down2), &[2]u16{ 0x55, 0xaa }));
542 try expect(mem.eql(u8, &@as([2]u8, down3), &[2]u8{ 0x55, 0xaa }));
543 }
544
545 fn doTheTestFloat() !void {
546 var vec = @splat(2, @as(f32, 1234.0));
547 var wider: @Vector(2, f64) = vec;
548 try expect(wider[0] == 1234.0);
549 try expect(wider[1] == 1234.0);
550 }
551 };
552
553 try S.doTheTest();
554 comptime try S.doTheTest();
555 try S.doTheTestFloat();
556 comptime try S.doTheTestFloat();
557}
558
559test "@floatCast cast down" {
560 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
561
562 {
563 var double: f64 = 0.001534;
564 var single = @floatCast(f32, double);
565 try expect(single == 0.001534);
566 }
567 {
568 const double: f64 = 0.001534;
569 const single = @floatCast(f32, double);
570 try expect(single == 0.001534);
571 }
572}
573
574test "peer type resolution: unreachable, error set, unreachable" {
575 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
576
577 const Error = error{
578 FileDescriptorAlreadyPresentInSet,
579 OperationCausesCircularLoop,
580 FileDescriptorNotRegistered,
581 SystemResources,
582 UserResourceLimitReached,
583 FileDescriptorIncompatibleWithEpoll,
584 Unexpected,
585 };
586 var err = Error.SystemResources;
587 const transformed_err = switch (err) {
588 error.FileDescriptorAlreadyPresentInSet => unreachable,
589 error.OperationCausesCircularLoop => unreachable,
590 error.FileDescriptorNotRegistered => unreachable,
591 error.SystemResources => error.SystemResources,
592 error.UserResourceLimitReached => error.UserResourceLimitReached,
593 error.FileDescriptorIncompatibleWithEpoll => unreachable,
594 error.Unexpected => unreachable,
595 };
596 try expect(transformed_err == error.SystemResources);
597}
598
599test "peer cast *[0]T to E![]const T" {
600 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
601
602 var buffer: [5]u8 = "abcde".*;
603 var buf: anyerror![]const u8 = buffer[0..];
604 var b = false;
605 var y = if (b) &[0]u8{} else buf;
606 try expect(mem.eql(u8, "abcde", y catch unreachable));
607}
608
609test "peer cast *[0]T to []const T" {
610 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
611
612 var buffer: [5]u8 = "abcde".*;
613 var buf: []const u8 = buffer[0..];
614 var b = false;
615 var y = if (b) &[0]u8{} else buf;
616 try expect(mem.eql(u8, "abcde", y));
617}
618
619test "peer resolution of string literals" {
620 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
621
622 const S = struct {
623 const E = enum { a, b, c, d };
624
625 fn doTheTest(e: E) !void {
626 const cmd = switch (e) {
627 .a => "one",
628 .b => "two",
629 .c => "three",
630 .d => "four",
631 };
632 try expect(mem.eql(u8, cmd, "two"));
633 }
634 };
635 try S.doTheTest(.b);
636 comptime try S.doTheTest(.b);
637}
638
639test "type coercion related to sentinel-termination" {
640 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
641
642 const S = struct {
643 fn doTheTest() !void {
644 // [:x]T to []T
645 {
646 var array = [4:0]i32{ 1, 2, 3, 4 };
647 var slice: [:0]i32 = &array;
648 var dest: []i32 = slice;
649 try expect(mem.eql(i32, dest, &[_]i32{ 1, 2, 3, 4 }));
650 }
651
652 // [*:x]T to [*]T
653 {
654 var array = [4:99]i32{ 1, 2, 3, 4 };
655 var dest: [*]i32 = &array;
656 try expect(dest[0] == 1);
657 try expect(dest[1] == 2);
658 try expect(dest[2] == 3);
659 try expect(dest[3] == 4);
660 try expect(dest[4] == 99);
661 }
662
663 // [N:x]T to [N]T
664 {
665 var array = [4:0]i32{ 1, 2, 3, 4 };
666 var dest: [4]i32 = array;
667 try expect(mem.eql(i32, &dest, &[_]i32{ 1, 2, 3, 4 }));
668 }
669
670 // *[N:x]T to *[N]T
671 {
672 var array = [4:0]i32{ 1, 2, 3, 4 };
673 var dest: *[4]i32 = &array;
674 try expect(mem.eql(i32, dest, &[_]i32{ 1, 2, 3, 4 }));
675 }
676
677 // [:x]T to [*:x]T
678 {
679 var array = [4:0]i32{ 1, 2, 3, 4 };
680 var slice: [:0]i32 = &array;
681 var dest: [*:0]i32 = slice;
682 try expect(dest[0] == 1);
683 try expect(dest[1] == 2);
684 try expect(dest[2] == 3);
685 try expect(dest[3] == 4);
686 try expect(dest[4] == 0);
687 }
688 }
689 };
690 try S.doTheTest();
691 comptime try S.doTheTest();
692}
693
694test "peer type resolution implicit cast to return type" {
695 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
696 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
697 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
698
699 const S = struct {
700 fn doTheTest() !void {
701 for ("hello") |c| _ = f(c);
702 }
703 fn f(c: u8) []const u8 {
704 return switch (c) {
705 'h', 'e' => &[_]u8{c}, // should cast to slice
706 'l', ' ' => &[_]u8{ c, '.' }, // should cast to slice
707 else => ([_]u8{c})[0..], // is a slice
708 };
709 }
710 };
711 try S.doTheTest();
712 comptime try S.doTheTest();
713}
714
715test "peer type resolution implicit cast to variable type" {
716 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
717 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
718 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
719
720 const S = struct {
721 fn doTheTest() !void {
722 var x: []const u8 = undefined;
723 for ("hello") |c| x = switch (c) {
724 'h', 'e' => &[_]u8{c}, // should cast to slice
725 'l', ' ' => &[_]u8{ c, '.' }, // should cast to slice
726 else => ([_]u8{c})[0..], // is a slice
727 };
728 }
729 };
730 try S.doTheTest();
731 comptime try S.doTheTest();
732}
733
734test "variable initialization uses result locations properly with regards to the type" {
735 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
736
737 var b = true;
738 const x: i32 = if (b) 1 else 2;
739 try expect(x == 1);
740}
741
742test "cast between C pointer with different but compatible types" {
743 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
744
745 const S = struct {
746 fn foo(arg: [*]c_ushort) u16 {
747 return arg[0];
748 }
749 fn doTheTest() !void {
750 var x = [_]u16{ 4, 2, 1, 3 };
751 try expect(foo(@ptrCast([*]u16, &x)) == 4);
752 }
753 };
754 try S.doTheTest();
755}
756
757test "peer type resolve string lit with sentinel-terminated mutable slice" {
758 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
759
760 var array: [4:0]u8 = undefined;
761 array[4] = 0; // TODO remove this when #4372 is solved
762 var slice: [:0]u8 = array[0..4 :0];
763 comptime try expect(@TypeOf(slice, "hi") == [:0]const u8);
764 comptime try expect(@TypeOf("hi", slice) == [:0]const u8);
765}
766
767test "peer type resolve array pointers, one of them const" {
768 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
769
770 var array1: [4]u8 = undefined;
771 const array2: [5]u8 = undefined;
772 comptime try expect(@TypeOf(&array1, &array2) == []const u8);
773 comptime try expect(@TypeOf(&array2, &array1) == []const u8);
774}
775
776test "peer type resolve array pointer and unknown pointer" {
777 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
778
779 const const_array: [4]u8 = undefined;
780 var array: [4]u8 = undefined;
781 var const_ptr: [*]const u8 = undefined;
782 var ptr: [*]u8 = undefined;
783
784 comptime try expect(@TypeOf(&array, ptr) == [*]u8);
785 comptime try expect(@TypeOf(ptr, &array) == [*]u8);
786
787 comptime try expect(@TypeOf(&const_array, ptr) == [*]const u8);
788 comptime try expect(@TypeOf(ptr, &const_array) == [*]const u8);
789
790 comptime try expect(@TypeOf(&array, const_ptr) == [*]const u8);
791 comptime try expect(@TypeOf(const_ptr, &array) == [*]const u8);
792
793 comptime try expect(@TypeOf(&const_array, const_ptr) == [*]const u8);
794 comptime try expect(@TypeOf(const_ptr, &const_array) == [*]const u8);
795}
796
797test "comptime float casts" {
798 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
799
800 const a = @intToFloat(comptime_float, 1);
801 try expect(a == 1);
802 try expect(@TypeOf(a) == comptime_float);
803 const b = @floatToInt(comptime_int, 2);
804 try expect(b == 2);
805 try expect(@TypeOf(b) == comptime_int);
806
807 try expectFloatToInt(comptime_int, 1234, i16, 1234);
808 try expectFloatToInt(comptime_float, 12.3, comptime_int, 12);
809}
test/behavior/cast_stage1.zig deleted-426
...@@ -1,426 +0,0 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const mem = std.mem;
4const maxInt = std.math.maxInt;
5const Vector = std.meta.Vector;
6const native_endian = @import("builtin").target.cpu.arch.endian();
7
8test "explicit cast from integer to error type" {
9 try testCastIntToErr(error.ItBroke);
10 comptime try testCastIntToErr(error.ItBroke);
11}
12fn testCastIntToErr(err: anyerror) !void {
13 const x = @errorToInt(err);
14 const y = @intToError(x);
15 try expect(error.ItBroke == y);
16}
17
18test "peer resolve array and const slice" {
19 try testPeerResolveArrayConstSlice(true);
20 comptime try testPeerResolveArrayConstSlice(true);
21}
22fn testPeerResolveArrayConstSlice(b: bool) !void {
23 const value1 = if (b) "aoeu" else @as([]const u8, "zz");
24 const value2 = if (b) @as([]const u8, "zz") else "aoeu";
25 try expect(mem.eql(u8, value1, "aoeu"));
26 try expect(mem.eql(u8, value2, "zz"));
27}
28
29test "implicitly cast from T to anyerror!?T" {
30 try castToOptionalTypeError(1);
31 comptime try castToOptionalTypeError(1);
32}
33
34const A = struct {
35 a: i32,
36};
37fn castToOptionalTypeError(z: i32) !void {
38 const x = @as(i32, 1);
39 const y: anyerror!?i32 = x;
40 try expect((try y).? == 1);
41
42 const f = z;
43 const g: anyerror!?i32 = f;
44 _ = g catch {};
45
46 const a = A{ .a = z };
47 const b: anyerror!?A = a;
48 try expect((b catch unreachable).?.a == 1);
49}
50
51test "implicitly cast from [0]T to anyerror![]T" {
52 try testCastZeroArrayToErrSliceMut();
53 comptime try testCastZeroArrayToErrSliceMut();
54}
55
56fn testCastZeroArrayToErrSliceMut() !void {
57 try expect((gimmeErrOrSlice() catch unreachable).len == 0);
58}
59
60fn gimmeErrOrSlice() anyerror![]u8 {
61 return &[_]u8{};
62}
63
64test "peer type resolution: [0]u8, []const u8, and anyerror![]u8" {
65 const S = struct {
66 fn doTheTest() anyerror!void {
67 {
68 var data = "hi".*;
69 const slice = data[0..];
70 try expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0);
71 try expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
72 }
73 {
74 var data: [2]u8 = "hi".*;
75 const slice = data[0..];
76 try expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0);
77 try expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
78 }
79 }
80 };
81 try S.doTheTest();
82 comptime try S.doTheTest();
83}
84fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) anyerror![]u8 {
85 if (a) {
86 return &[_]u8{};
87 }
88
89 return slice[0..1];
90}
91
92test "implicit cast from *const [N]T to []const T" {
93 try testCastConstArrayRefToConstSlice();
94 comptime try testCastConstArrayRefToConstSlice();
95}
96
97fn testCastConstArrayRefToConstSlice() !void {
98 {
99 const blah = "aoeu".*;
100 const const_array_ref = &blah;
101 try expect(@TypeOf(const_array_ref) == *const [4:0]u8);
102 const slice: []const u8 = const_array_ref;
103 try expect(mem.eql(u8, slice, "aoeu"));
104 }
105 {
106 const blah: [4]u8 = "aoeu".*;
107 const const_array_ref = &blah;
108 try expect(@TypeOf(const_array_ref) == *const [4]u8);
109 const slice: []const u8 = const_array_ref;
110 try expect(mem.eql(u8, slice, "aoeu"));
111 }
112}
113
114test "peer type resolution: error and [N]T" {
115 try expect(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
116 comptime try expect(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
117 try expect(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));
118 comptime try expect(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));
119}
120
121fn testPeerErrorAndArray(x: u8) anyerror![]const u8 {
122 return switch (x) {
123 0x00 => "OK",
124 else => error.BadValue,
125 };
126}
127fn testPeerErrorAndArray2(x: u8) anyerror![]const u8 {
128 return switch (x) {
129 0x00 => "OK",
130 0x01 => "OKK",
131 else => error.BadValue,
132 };
133}
134
135test "single-item pointer of array to slice to unknown length pointer" {
136 try testCastPtrOfArrayToSliceAndPtr();
137 comptime try testCastPtrOfArrayToSliceAndPtr();
138}
139
140fn testCastPtrOfArrayToSliceAndPtr() !void {
141 {
142 var array = "aoeu".*;
143 const x: [*]u8 = &array;
144 x[0] += 1;
145 try expect(mem.eql(u8, array[0..], "boeu"));
146 const y: []u8 = &array;
147 y[0] += 1;
148 try expect(mem.eql(u8, array[0..], "coeu"));
149 }
150 {
151 var array: [4]u8 = "aoeu".*;
152 const x: [*]u8 = &array;
153 x[0] += 1;
154 try expect(mem.eql(u8, array[0..], "boeu"));
155 const y: []u8 = &array;
156 y[0] += 1;
157 try expect(mem.eql(u8, array[0..], "coeu"));
158 }
159}
160
161test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
162 const window_name = [1][*]const u8{"window name"};
163 const x: [*]const ?[*]const u8 = &window_name;
164 try expect(mem.eql(u8, std.mem.sliceTo(@ptrCast([*:0]const u8, x[0].?), 0), "window name"));
165}
166
167test "vector casts" {
168 const S = struct {
169 fn doTheTest() !void {
170 // Upcast (implicit, equivalent to @intCast)
171 var up0: Vector(2, u8) = [_]u8{ 0x55, 0xaa };
172 var up1 = @as(Vector(2, u16), up0);
173 var up2 = @as(Vector(2, u32), up0);
174 var up3 = @as(Vector(2, u64), up0);
175 // Downcast (safety-checked)
176 var down0 = up3;
177 var down1 = @intCast(Vector(2, u32), down0);
178 var down2 = @intCast(Vector(2, u16), down0);
179 var down3 = @intCast(Vector(2, u8), down0);
180
181 try expect(mem.eql(u16, &@as([2]u16, up1), &[2]u16{ 0x55, 0xaa }));
182 try expect(mem.eql(u32, &@as([2]u32, up2), &[2]u32{ 0x55, 0xaa }));
183 try expect(mem.eql(u64, &@as([2]u64, up3), &[2]u64{ 0x55, 0xaa }));
184
185 try expect(mem.eql(u32, &@as([2]u32, down1), &[2]u32{ 0x55, 0xaa }));
186 try expect(mem.eql(u16, &@as([2]u16, down2), &[2]u16{ 0x55, 0xaa }));
187 try expect(mem.eql(u8, &@as([2]u8, down3), &[2]u8{ 0x55, 0xaa }));
188 }
189
190 fn doTheTestFloat() !void {
191 var vec = @splat(2, @as(f32, 1234.0));
192 var wider: Vector(2, f64) = vec;
193 try expect(wider[0] == 1234.0);
194 try expect(wider[1] == 1234.0);
195 }
196 };
197
198 try S.doTheTest();
199 comptime try S.doTheTest();
200 try S.doTheTestFloat();
201 comptime try S.doTheTestFloat();
202}
203
204test "@floatCast cast down" {
205 {
206 var double: f64 = 0.001534;
207 var single = @floatCast(f32, double);
208 try expect(single == 0.001534);
209 }
210 {
211 const double: f64 = 0.001534;
212 const single = @floatCast(f32, double);
213 try expect(single == 0.001534);
214 }
215}
216
217test "peer type resolution: unreachable, error set, unreachable" {
218 const Error = error{
219 FileDescriptorAlreadyPresentInSet,
220 OperationCausesCircularLoop,
221 FileDescriptorNotRegistered,
222 SystemResources,
223 UserResourceLimitReached,
224 FileDescriptorIncompatibleWithEpoll,
225 Unexpected,
226 };
227 var err = Error.SystemResources;
228 const transformed_err = switch (err) {
229 error.FileDescriptorAlreadyPresentInSet => unreachable,
230 error.OperationCausesCircularLoop => unreachable,
231 error.FileDescriptorNotRegistered => unreachable,
232 error.SystemResources => error.SystemResources,
233 error.UserResourceLimitReached => error.UserResourceLimitReached,
234 error.FileDescriptorIncompatibleWithEpoll => unreachable,
235 error.Unexpected => unreachable,
236 };
237 try expect(transformed_err == error.SystemResources);
238}
239
240test "peer cast *[0]T to E![]const T" {
241 var buffer: [5]u8 = "abcde".*;
242 var buf: anyerror![]const u8 = buffer[0..];
243 var b = false;
244 var y = if (b) &[0]u8{} else buf;
245 try expect(mem.eql(u8, "abcde", y catch unreachable));
246}
247
248test "peer cast *[0]T to []const T" {
249 var buffer: [5]u8 = "abcde".*;
250 var buf: []const u8 = buffer[0..];
251 var b = false;
252 var y = if (b) &[0]u8{} else buf;
253 try expect(mem.eql(u8, "abcde", y));
254}
255
256test "peer resolution of string literals" {
257 const S = struct {
258 const E = enum { a, b, c, d };
259
260 fn doTheTest(e: E) !void {
261 const cmd = switch (e) {
262 .a => "one",
263 .b => "two",
264 .c => "three",
265 .d => "four",
266 };
267 try expect(mem.eql(u8, cmd, "two"));
268 }
269 };
270 try S.doTheTest(.b);
271 comptime try S.doTheTest(.b);
272}
273
274test "type coercion related to sentinel-termination" {
275 const S = struct {
276 fn doTheTest() !void {
277 // [:x]T to []T
278 {
279 var array = [4:0]i32{ 1, 2, 3, 4 };
280 var slice: [:0]i32 = &array;
281 var dest: []i32 = slice;
282 try expect(mem.eql(i32, dest, &[_]i32{ 1, 2, 3, 4 }));
283 }
284
285 // [*:x]T to [*]T
286 {
287 var array = [4:99]i32{ 1, 2, 3, 4 };
288 var dest: [*]i32 = &array;
289 try expect(dest[0] == 1);
290 try expect(dest[1] == 2);
291 try expect(dest[2] == 3);
292 try expect(dest[3] == 4);
293 try expect(dest[4] == 99);
294 }
295
296 // [N:x]T to [N]T
297 {
298 var array = [4:0]i32{ 1, 2, 3, 4 };
299 var dest: [4]i32 = array;
300 try expect(mem.eql(i32, &dest, &[_]i32{ 1, 2, 3, 4 }));
301 }
302
303 // *[N:x]T to *[N]T
304 {
305 var array = [4:0]i32{ 1, 2, 3, 4 };
306 var dest: *[4]i32 = &array;
307 try expect(mem.eql(i32, dest, &[_]i32{ 1, 2, 3, 4 }));
308 }
309
310 // [:x]T to [*:x]T
311 {
312 var array = [4:0]i32{ 1, 2, 3, 4 };
313 var slice: [:0]i32 = &array;
314 var dest: [*:0]i32 = slice;
315 try expect(dest[0] == 1);
316 try expect(dest[1] == 2);
317 try expect(dest[2] == 3);
318 try expect(dest[3] == 4);
319 try expect(dest[4] == 0);
320 }
321 }
322 };
323 try S.doTheTest();
324 comptime try S.doTheTest();
325}
326
327test "peer type resolution implicit cast to return type" {
328 const S = struct {
329 fn doTheTest() !void {
330 for ("hello") |c| _ = f(c);
331 }
332 fn f(c: u8) []const u8 {
333 return switch (c) {
334 'h', 'e' => &[_]u8{c}, // should cast to slice
335 'l', ' ' => &[_]u8{ c, '.' }, // should cast to slice
336 else => ([_]u8{c})[0..], // is a slice
337 };
338 }
339 };
340 try S.doTheTest();
341 comptime try S.doTheTest();
342}
343
344test "peer type resolution implicit cast to variable type" {
345 const S = struct {
346 fn doTheTest() !void {
347 var x: []const u8 = undefined;
348 for ("hello") |c| x = switch (c) {
349 'h', 'e' => &[_]u8{c}, // should cast to slice
350 'l', ' ' => &[_]u8{ c, '.' }, // should cast to slice
351 else => ([_]u8{c})[0..], // is a slice
352 };
353 }
354 };
355 try S.doTheTest();
356 comptime try S.doTheTest();
357}
358
359test "variable initialization uses result locations properly with regards to the type" {
360 var b = true;
361 const x: i32 = if (b) 1 else 2;
362 try expect(x == 1);
363}
364
365test "cast between C pointer with different but compatible types" {
366 const S = struct {
367 fn foo(arg: [*]c_ushort) u16 {
368 return arg[0];
369 }
370 fn doTheTest() !void {
371 var x = [_]u16{ 4, 2, 1, 3 };
372 try expect(foo(@ptrCast([*]u16, &x)) == 4);
373 }
374 };
375 try S.doTheTest();
376}
377
378test "peer type resolve string lit with sentinel-terminated mutable slice" {
379 var array: [4:0]u8 = undefined;
380 array[4] = 0; // TODO remove this when #4372 is solved
381 var slice: [:0]u8 = array[0..4 :0];
382 comptime try expect(@TypeOf(slice, "hi") == [:0]const u8);
383 comptime try expect(@TypeOf("hi", slice) == [:0]const u8);
384}
385
386test "peer type resolve array pointers, one of them const" {
387 var array1: [4]u8 = undefined;
388 const array2: [5]u8 = undefined;
389 comptime try expect(@TypeOf(&array1, &array2) == []const u8);
390 comptime try expect(@TypeOf(&array2, &array1) == []const u8);
391}
392
393test "peer type resolve array pointer and unknown pointer" {
394 const const_array: [4]u8 = undefined;
395 var array: [4]u8 = undefined;
396 var const_ptr: [*]const u8 = undefined;
397 var ptr: [*]u8 = undefined;
398
399 comptime try expect(@TypeOf(&array, ptr) == [*]u8);
400 comptime try expect(@TypeOf(ptr, &array) == [*]u8);
401
402 comptime try expect(@TypeOf(&const_array, ptr) == [*]const u8);
403 comptime try expect(@TypeOf(ptr, &const_array) == [*]const u8);
404
405 comptime try expect(@TypeOf(&array, const_ptr) == [*]const u8);
406 comptime try expect(@TypeOf(const_ptr, &array) == [*]const u8);
407
408 comptime try expect(@TypeOf(&const_array, const_ptr) == [*]const u8);
409 comptime try expect(@TypeOf(const_ptr, &const_array) == [*]const u8);
410}
411
412test "comptime float casts" {
413 const a = @intToFloat(comptime_float, 1);
414 try expect(a == 1);
415 try expect(@TypeOf(a) == comptime_float);
416 const b = @floatToInt(comptime_int, 2);
417 try expect(b == 2);
418 try expect(@TypeOf(b) == comptime_int);
419
420 try expectFloatToInt(comptime_int, 1234, i16, 1234);
421 try expectFloatToInt(comptime_float, 12.3, comptime_int, 12);
422}
423
424fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) !void {
425 try expect(@floatToInt(I, f) == i);
426}
test/behavior/defer.zig+56
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("std");2const std = @import("std");
2const expect = std.testing.expect;3const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;4const expectEqual = std.testing.expectEqual;
...@@ -61,3 +62,58 @@ test "return variable while defer expression in scope to modify it" {...@@ -61,3 +62,58 @@ test "return variable while defer expression in scope to modify it" {
61 try S.doTheTest();62 try S.doTheTest();
62 comptime try S.doTheTest();63 comptime try S.doTheTest();
63}64}
65
66var result: [3]u8 = undefined;
67var index: usize = undefined;
68
69fn runSomeErrorDefers(x: bool) !bool {
70 index = 0;
71 defer {
72 result[index] = 'a';
73 index += 1;
74 }
75 errdefer {
76 result[index] = 'b';
77 index += 1;
78 }
79 defer {
80 result[index] = 'c';
81 index += 1;
82 }
83 return if (x) x else error.FalseNotAllowed;
84}
85
86test "mixing normal and error defers" {
87 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
88
89 try expect(runSomeErrorDefers(true) catch unreachable);
90 try expect(result[0] == 'c');
91 try expect(result[1] == 'a');
92
93 const ok = runSomeErrorDefers(false) catch |err| x: {
94 try expect(err == error.FalseNotAllowed);
95 break :x true;
96 };
97 try expect(ok);
98 try expect(result[0] == 'c');
99 try expect(result[1] == 'b');
100 try expect(result[2] == 'a');
101}
102
103test "errdefer with payload" {
104 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
105
106 const S = struct {
107 fn foo() !i32 {
108 errdefer |a| {
109 expectEqual(error.One, a) catch @panic("test failure");
110 }
111 return error.One;
112 }
113 fn doTheTest() !void {
114 try expectError(error.One, foo());
115 }
116 };
117 try S.doTheTest();
118 comptime try S.doTheTest();
119}
test/behavior/defer_stage1.zig deleted-55
...@@ -1,55 +0,0 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;
4const expectError = std.testing.expectError;
5
6var result: [3]u8 = undefined;
7var index: usize = undefined;
8
9fn runSomeErrorDefers(x: bool) !bool {
10 index = 0;
11 defer {
12 result[index] = 'a';
13 index += 1;
14 }
15 errdefer {
16 result[index] = 'b';
17 index += 1;
18 }
19 defer {
20 result[index] = 'c';
21 index += 1;
22 }
23 return if (x) x else error.FalseNotAllowed;
24}
25
26test "mixing normal and error defers" {
27 try expect(runSomeErrorDefers(true) catch unreachable);
28 try expect(result[0] == 'c');
29 try expect(result[1] == 'a');
30
31 const ok = runSomeErrorDefers(false) catch |err| x: {
32 try expect(err == error.FalseNotAllowed);
33 break :x true;
34 };
35 try expect(ok);
36 try expect(result[0] == 'c');
37 try expect(result[1] == 'b');
38 try expect(result[2] == 'a');
39}
40
41test "errdefer with payload" {
42 const S = struct {
43 fn foo() !i32 {
44 errdefer |a| {
45 expectEqual(error.One, a) catch @panic("test failure");
46 }
47 return error.One;
48 }
49 fn doTheTest() !void {
50 try expectError(error.One, foo());
51 }
52 };
53 try S.doTheTest();
54 comptime try S.doTheTest();
55}
test/behavior/enum.zig+102
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("std");2const std = @import("std");
2const expect = std.testing.expect;3const expect = std.testing.expect;
3const mem = std.mem;4const mem = std.mem;
...@@ -870,3 +871,104 @@ test "method call on an enum" {...@@ -870,3 +871,104 @@ test "method call on an enum" {
870 try S.doTheTest();871 try S.doTheTest();
871 comptime try S.doTheTest();872 comptime try S.doTheTest();
872}873}
874
875test "enum value allocation" {
876 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
877
878 const LargeEnum = enum(u32) {
879 A0 = 0x80000000,
880 A1,
881 A2,
882 };
883
884 try expect(@enumToInt(LargeEnum.A0) == 0x80000000);
885 try expect(@enumToInt(LargeEnum.A1) == 0x80000001);
886 try expect(@enumToInt(LargeEnum.A2) == 0x80000002);
887}
888
889test "enum literal casting to tagged union" {
890 const Arch = union(enum) {
891 x86_64,
892 arm: Arm32,
893
894 const Arm32 = enum {
895 v8_5a,
896 v8_4a,
897 };
898 };
899
900 var t = true;
901 var x: Arch = .x86_64;
902 var y = if (t) x else .x86_64;
903 switch (y) {
904 .x86_64 => {},
905 else => @panic("fail"),
906 }
907}
908
909const Bar = enum { A, B, C, D };
910
911test "enum literal casting to error union with payload enum" {
912 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
913
914 var bar: error{B}!Bar = undefined;
915 bar = .B; // should never cast to the error set
916
917 try expect((try bar) == Bar.B);
918}
919
920test "exporting enum type and value" {
921 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
922
923 const S = struct {
924 const E = enum(c_int) { one, two };
925 comptime {
926 @export(E, .{ .name = "E" });
927 }
928 const e: E = .two;
929 comptime {
930 @export(e, .{ .name = "e" });
931 }
932 };
933 try expect(S.e == .two);
934}
935
936test "constant enum initialization with differing sizes" {
937 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
938
939 try test3_1(test3_foo);
940 try test3_2(test3_bar);
941}
942const Test3Foo = union(enum) {
943 One: void,
944 Two: f32,
945 Three: Test3Point,
946};
947const Test3Point = struct {
948 x: i32,
949 y: i32,
950};
951const test3_foo = Test3Foo{
952 .Three = Test3Point{
953 .x = 3,
954 .y = 4,
955 },
956};
957const test3_bar = Test3Foo{ .Two = 13 };
958fn test3_1(f: Test3Foo) !void {
959 switch (f) {
960 Test3Foo.Three => |pt| {
961 try expect(pt.x == 3);
962 try expect(pt.y == 4);
963 },
964 else => unreachable,
965 }
966}
967fn test3_2(f: Test3Foo) !void {
968 switch (f) {
969 Test3Foo.Two => |x| {
970 try expect(x == 13);
971 },
972 else => unreachable,
973 }
974}
test/behavior/enum_stage1.zig deleted-97
...@@ -1,97 +0,0 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const mem = std.mem;
4const Tag = std.meta.Tag;
5
6test "enum value allocation" {
7 const LargeEnum = enum(u32) {
8 A0 = 0x80000000,
9 A1,
10 A2,
11 };
12
13 try expect(@enumToInt(LargeEnum.A0) == 0x80000000);
14 try expect(@enumToInt(LargeEnum.A1) == 0x80000001);
15 try expect(@enumToInt(LargeEnum.A2) == 0x80000002);
16}
17
18test "enum literal casting to tagged union" {
19 const Arch = union(enum) {
20 x86_64,
21 arm: Arm32,
22
23 const Arm32 = enum {
24 v8_5a,
25 v8_4a,
26 };
27 };
28
29 var t = true;
30 var x: Arch = .x86_64;
31 var y = if (t) x else .x86_64;
32 switch (y) {
33 .x86_64 => {},
34 else => @panic("fail"),
35 }
36}
37
38const Bar = enum { A, B, C, D };
39
40test "enum literal casting to error union with payload enum" {
41 var bar: error{B}!Bar = undefined;
42 bar = .B; // should never cast to the error set
43
44 try expect((try bar) == Bar.B);
45}
46
47test "exporting enum type and value" {
48 const S = struct {
49 const E = enum(c_int) { one, two };
50 comptime {
51 @export(E, .{ .name = "E" });
52 }
53 const e: E = .two;
54 comptime {
55 @export(e, .{ .name = "e" });
56 }
57 };
58 try expect(S.e == .two);
59}
60
61test "constant enum initialization with differing sizes" {
62 try test3_1(test3_foo);
63 try test3_2(test3_bar);
64}
65const Test3Foo = union(enum) {
66 One: void,
67 Two: f32,
68 Three: Test3Point,
69};
70const Test3Point = struct {
71 x: i32,
72 y: i32,
73};
74const test3_foo = Test3Foo{
75 .Three = Test3Point{
76 .x = 3,
77 .y = 4,
78 },
79};
80const test3_bar = Test3Foo{ .Two = 13 };
81fn test3_1(f: Test3Foo) !void {
82 switch (f) {
83 Test3Foo.Three => |pt| {
84 try expect(pt.x == 3);
85 try expect(pt.y == 4);
86 },
87 else => unreachable,
88 }
89}
90fn test3_2(f: Test3Foo) !void {
91 switch (f) {
92 Test3Foo.Two => |x| {
93 try expect(x == 13);
94 },
95 else => unreachable,
96 }
97}
test/behavior/eval.zig+306
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("std");2const std = @import("std");
2const expect = std.testing.expect;3const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;4const expectEqual = std.testing.expectEqual;
...@@ -492,3 +493,308 @@ test "@tagName of @typeInfo" {...@@ -492,3 +493,308 @@ test "@tagName of @typeInfo" {
492 const str = @tagName(@typeInfo(u8));493 const str = @tagName(@typeInfo(u8));
493 try expect(std.mem.eql(u8, str, "Int"));494 try expect(std.mem.eql(u8, str, "Int"));
494}495}
496
497test "static eval list init" {
498 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
499
500 try expect(static_vec3.data[2] == 1.0);
501 try expect(vec3(0.0, 0.0, 3.0).data[2] == 3.0);
502}
503const static_vec3 = vec3(0.0, 0.0, 1.0);
504pub const Vec3 = struct {
505 data: [3]f32,
506};
507pub fn vec3(x: f32, y: f32, z: f32) Vec3 {
508 return Vec3{
509 .data = [_]f32{ x, y, z },
510 };
511}
512
513test "inlined loop has array literal with elided runtime scope on first iteration but not second iteration" {
514 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
515
516 var runtime = [1]i32{3};
517 comptime var i: usize = 0;
518 inline while (i < 2) : (i += 1) {
519 const result = if (i == 0) [1]i32{2} else runtime;
520 _ = result;
521 }
522 comptime {
523 try expect(i == 2);
524 }
525}
526
527test "eval @setFloatMode at compile-time" {
528 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
529
530 const result = comptime fnWithFloatMode();
531 try expect(result == 1234.0);
532}
533
534fn fnWithFloatMode() f32 {
535 @setFloatMode(std.builtin.FloatMode.Strict);
536 return 1234.0;
537}
538
539test "call method on bound fn referring to var instance" {
540 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
541
542 try expect(bound_fn() == 1237);
543}
544
545const SimpleStruct = struct {
546 field: i32,
547
548 fn method(self: *const SimpleStruct) i32 {
549 return self.field + 3;
550 }
551};
552
553var simple_struct = SimpleStruct{ .field = 1234 };
554
555const bound_fn = simple_struct.method;
556
557test "ptr to local array argument at comptime" {
558 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
559
560 comptime {
561 var bytes: [10]u8 = undefined;
562 modifySomeBytes(bytes[0..]);
563 try expect(bytes[0] == 'a');
564 try expect(bytes[9] == 'b');
565 }
566}
567
568fn modifySomeBytes(bytes: []u8) void {
569 bytes[0] = 'a';
570 bytes[9] = 'b';
571}
572
573test "comparisons 0 <= uint and 0 > uint should be comptime" {
574 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
575
576 testCompTimeUIntComparisons(1234);
577}
578fn testCompTimeUIntComparisons(x: u32) void {
579 if (!(0 <= x)) {
580 @compileError("this condition should be comptime known");
581 }
582 if (0 > x) {
583 @compileError("this condition should be comptime known");
584 }
585 if (!(x >= 0)) {
586 @compileError("this condition should be comptime known");
587 }
588 if (x < 0) {
589 @compileError("this condition should be comptime known");
590 }
591}
592
593const hi1 = "hi";
594const hi2 = hi1;
595test "const global shares pointer with other same one" {
596 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
597
598 try assertEqualPtrs(&hi1[0], &hi2[0]);
599 comptime try expect(&hi1[0] == &hi2[0]);
600}
601fn assertEqualPtrs(ptr1: *const u8, ptr2: *const u8) !void {
602 try expect(ptr1 == ptr2);
603}
604
605test "float literal at compile time not lossy" {
606 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
607
608 try expect(16777216.0 + 1.0 == 16777217.0);
609 try expect(9007199254740992.0 + 1.0 == 9007199254740993.0);
610}
611
612test "f128 at compile time is lossy" {
613 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
614
615 try expect(@as(f128, 10384593717069655257060992658440192.0) + 1 == 10384593717069655257060992658440192.0);
616}
617
618test "string literal used as comptime slice is memoized" {
619 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
620
621 const a = "link";
622 const b = "link";
623 comptime try expect(TypeWithCompTimeSlice(a).Node == TypeWithCompTimeSlice(b).Node);
624 comptime try expect(TypeWithCompTimeSlice("link").Node == TypeWithCompTimeSlice("link").Node);
625}
626
627pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) type {
628 _ = field_name;
629 return struct {
630 pub const Node = struct {};
631 };
632}
633
634test "comptime function with mutable pointer is not memoized" {
635 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
636
637 comptime {
638 var x: i32 = 1;
639 const ptr = &x;
640 increment(ptr);
641 increment(ptr);
642 try expect(x == 3);
643 }
644}
645
646fn increment(value: *i32) void {
647 value.* += 1;
648}
649
650test "const ptr to comptime mutable data is not memoized" {
651 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
652
653 comptime {
654 var foo = SingleFieldStruct{ .x = 1 };
655 try expect(foo.read_x() == 1);
656 foo.x = 2;
657 try expect(foo.read_x() == 2);
658 }
659}
660
661const SingleFieldStruct = struct {
662 x: i32,
663
664 fn read_x(self: *const SingleFieldStruct) i32 {
665 return self.x;
666 }
667};
668
669test "function which returns struct with type field causes implicit comptime" {
670 const ty = wrap(i32).T;
671 try expect(ty == i32);
672}
673
674const Wrapper = struct {
675 T: type,
676};
677
678fn wrap(comptime T: type) Wrapper {
679 return Wrapper{ .T = T };
680}
681
682test "call method with comptime pass-by-non-copying-value self parameter" {
683 const S = struct {
684 a: u8,
685
686 fn b(comptime s: @This()) u8 {
687 return s.a;
688 }
689 };
690
691 const s = S{ .a = 2 };
692 var b = s.b();
693 try expect(b == 2);
694}
695
696test "setting backward branch quota just before a generic fn call" {
697 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
698
699 @setEvalBranchQuota(1001);
700 loopNTimes(1001);
701}
702
703fn loopNTimes(comptime n: usize) void {
704 comptime var i = 0;
705 inline while (i < n) : (i += 1) {}
706}
707
708test "variable inside inline loop that has different types on different iterations" {
709 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
710
711 try testVarInsideInlineLoop(.{ true, @as(u32, 42) });
712}
713
714fn testVarInsideInlineLoop(args: anytype) !void {
715 comptime var i = 0;
716 inline while (i < args.len) : (i += 1) {
717 const x = args[i];
718 if (i == 0) try expect(x);
719 if (i == 1) try expect(x == 42);
720 }
721}
722
723test "bit shift a u1" {
724 // note: when debugging this test case for stage2, be sure to run it
725 // in valgrind. I noticed the rhs value is undefined in the lowering
726 // of the const value.
727 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
728
729 var x: u1 = 1;
730 var y = x << 0;
731 try expect(y == 1);
732}
733
734test "*align(1) u16 is the same as *align(1:0:2) u16" {
735 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
736
737 comptime {
738 try expect(*align(1:0:2) u16 == *align(1) u16);
739 try expect(*align(2:0:2) u16 == *u16);
740 }
741}
742
743test "array concatenation forces comptime" {
744 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
745
746 var a = oneItem(3) ++ oneItem(4);
747 try expect(std.mem.eql(i32, &a, &[_]i32{ 3, 4 }));
748}
749
750test "array multiplication forces comptime" {
751 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
752
753 var a = oneItem(3) ** scalar(2);
754 try expect(std.mem.eql(i32, &a, &[_]i32{ 3, 3 }));
755}
756
757fn oneItem(x: i32) [1]i32 {
758 return [_]i32{x};
759}
760
761fn scalar(x: u32) u32 {
762 return x;
763}
764
765test "comptime assign int to optional int" {
766 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
767
768 comptime {
769 var x: ?i32 = null;
770 x = 2;
771 x.? *= 10;
772 try expectEqual(20, x.?);
773 }
774}
775
776test "two comptime calls with array default initialized to undefined" {
777 const S = struct {
778 const CrossTarget = struct {
779 dynamic_linker: DynamicLinker = DynamicLinker{},
780
781 pub fn parse() void {
782 var result: CrossTarget = .{};
783 result.getCpuArch();
784 }
785
786 pub fn getCpuArch(self: CrossTarget) void {
787 _ = self;
788 }
789 };
790
791 const DynamicLinker = struct {
792 buffer: [255]u8 = undefined,
793 };
794 };
795
796 comptime {
797 S.CrossTarget.parse();
798 S.CrossTarget.parse();
799 }
800}
test/behavior/eval_stage1.zig deleted-266
...@@ -1,266 +0,0 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;
4
5test "static eval list init" {
6 try expect(static_vec3.data[2] == 1.0);
7 try expect(vec3(0.0, 0.0, 3.0).data[2] == 3.0);
8}
9const static_vec3 = vec3(0.0, 0.0, 1.0);
10pub const Vec3 = struct {
11 data: [3]f32,
12};
13pub fn vec3(x: f32, y: f32, z: f32) Vec3 {
14 return Vec3{
15 .data = [_]f32{ x, y, z },
16 };
17}
18
19test "inlined loop has array literal with elided runtime scope on first iteration but not second iteration" {
20 var runtime = [1]i32{3};
21 comptime var i: usize = 0;
22 inline while (i < 2) : (i += 1) {
23 const result = if (i == 0) [1]i32{2} else runtime;
24 _ = result;
25 }
26 comptime {
27 try expect(i == 2);
28 }
29}
30
31test "eval @setFloatMode at compile-time" {
32 const result = comptime fnWithFloatMode();
33 try expect(result == 1234.0);
34}
35
36fn fnWithFloatMode() f32 {
37 @setFloatMode(std.builtin.FloatMode.Strict);
38 return 1234.0;
39}
40
41const SimpleStruct = struct {
42 field: i32,
43
44 fn method(self: *const SimpleStruct) i32 {
45 return self.field + 3;
46 }
47};
48
49var simple_struct = SimpleStruct{ .field = 1234 };
50
51const bound_fn = simple_struct.method;
52
53test "call method on bound fn referring to var instance" {
54 try expect(bound_fn() == 1237);
55}
56
57test "ptr to local array argument at comptime" {
58 comptime {
59 var bytes: [10]u8 = undefined;
60 modifySomeBytes(bytes[0..]);
61 try expect(bytes[0] == 'a');
62 try expect(bytes[9] == 'b');
63 }
64}
65
66fn modifySomeBytes(bytes: []u8) void {
67 bytes[0] = 'a';
68 bytes[9] = 'b';
69}
70
71test "comparisons 0 <= uint and 0 > uint should be comptime" {
72 testCompTimeUIntComparisons(1234);
73}
74fn testCompTimeUIntComparisons(x: u32) void {
75 if (!(0 <= x)) {
76 @compileError("this condition should be comptime known");
77 }
78 if (0 > x) {
79 @compileError("this condition should be comptime known");
80 }
81 if (!(x >= 0)) {
82 @compileError("this condition should be comptime known");
83 }
84 if (x < 0) {
85 @compileError("this condition should be comptime known");
86 }
87}
88
89const hi1 = "hi";
90const hi2 = hi1;
91test "const global shares pointer with other same one" {
92 try assertEqualPtrs(&hi1[0], &hi2[0]);
93 comptime try expect(&hi1[0] == &hi2[0]);
94}
95fn assertEqualPtrs(ptr1: *const u8, ptr2: *const u8) !void {
96 try expect(ptr1 == ptr2);
97}
98
99test "float literal at compile time not lossy" {
100 try expect(16777216.0 + 1.0 == 16777217.0);
101 try expect(9007199254740992.0 + 1.0 == 9007199254740993.0);
102}
103
104test "f128 at compile time is lossy" {
105 try expect(@as(f128, 10384593717069655257060992658440192.0) + 1 == 10384593717069655257060992658440192.0);
106}
107
108pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) type {
109 _ = field_name;
110 return struct {
111 pub const Node = struct {};
112 };
113}
114
115test "string literal used as comptime slice is memoized" {
116 const a = "link";
117 const b = "link";
118 comptime try expect(TypeWithCompTimeSlice(a).Node == TypeWithCompTimeSlice(b).Node);
119 comptime try expect(TypeWithCompTimeSlice("link").Node == TypeWithCompTimeSlice("link").Node);
120}
121
122test "comptime function with mutable pointer is not memoized" {
123 comptime {
124 var x: i32 = 1;
125 const ptr = &x;
126 increment(ptr);
127 increment(ptr);
128 try expect(x == 3);
129 }
130}
131
132fn increment(value: *i32) void {
133 value.* += 1;
134}
135
136const SingleFieldStruct = struct {
137 x: i32,
138
139 fn read_x(self: *const SingleFieldStruct) i32 {
140 return self.x;
141 }
142};
143test "const ptr to comptime mutable data is not memoized" {
144 comptime {
145 var foo = SingleFieldStruct{ .x = 1 };
146 try expect(foo.read_x() == 1);
147 foo.x = 2;
148 try expect(foo.read_x() == 2);
149 }
150}
151
152const Wrapper = struct {
153 T: type,
154};
155
156fn wrap(comptime T: type) Wrapper {
157 return Wrapper{ .T = T };
158}
159
160test "function which returns struct with type field causes implicit comptime" {
161 const ty = wrap(i32).T;
162 try expect(ty == i32);
163}
164
165test "call method with comptime pass-by-non-copying-value self parameter" {
166 const S = struct {
167 a: u8,
168
169 fn b(comptime s: @This()) u8 {
170 return s.a;
171 }
172 };
173
174 const s = S{ .a = 2 };
175 var b = s.b();
176 try expect(b == 2);
177}
178
179test "setting backward branch quota just before a generic fn call" {
180 @setEvalBranchQuota(1001);
181 loopNTimes(1001);
182}
183
184fn loopNTimes(comptime n: usize) void {
185 comptime var i = 0;
186 inline while (i < n) : (i += 1) {}
187}
188
189test "variable inside inline loop that has different types on different iterations" {
190 try testVarInsideInlineLoop(.{ true, @as(u32, 42) });
191}
192
193fn testVarInsideInlineLoop(args: anytype) !void {
194 comptime var i = 0;
195 inline while (i < args.len) : (i += 1) {
196 const x = args[i];
197 if (i == 0) try expect(x);
198 if (i == 1) try expect(x == 42);
199 }
200}
201
202test "bit shift a u1" {
203 var x: u1 = 1;
204 var y = x << 0;
205 try expect(y == 1);
206}
207
208test "*align(1) u16 is the same as *align(1:0:2) u16" {
209 comptime {
210 try expect(*align(1:0:2) u16 == *align(1) u16);
211 try expect(*align(2:0:2) u16 == *u16);
212 }
213}
214
215test "array concatenation forces comptime" {
216 var a = oneItem(3) ++ oneItem(4);
217 try expect(std.mem.eql(i32, &a, &[_]i32{ 3, 4 }));
218}
219
220test "array multiplication forces comptime" {
221 var a = oneItem(3) ** scalar(2);
222 try expect(std.mem.eql(i32, &a, &[_]i32{ 3, 3 }));
223}
224
225fn oneItem(x: i32) [1]i32 {
226 return [_]i32{x};
227}
228
229fn scalar(x: u32) u32 {
230 return x;
231}
232
233test "comptime assign int to optional int" {
234 comptime {
235 var x: ?i32 = null;
236 x = 2;
237 x.? *= 10;
238 try expectEqual(20, x.?);
239 }
240}
241
242test "two comptime calls with array default initialized to undefined" {
243 const S = struct {
244 const CrossTarget = struct {
245 dynamic_linker: DynamicLinker = DynamicLinker{},
246
247 pub fn parse() void {
248 var result: CrossTarget = .{};
249 result.getCpuArch();
250 }
251
252 pub fn getCpuArch(self: CrossTarget) void {
253 _ = self;
254 }
255 };
256
257 const DynamicLinker = struct {
258 buffer: [255]u8 = undefined,
259 };
260 };
261
262 comptime {
263 S.CrossTarget.parse();
264 S.CrossTarget.parse();
265 }
266}
test/behavior/fn.zig+98
...@@ -250,3 +250,101 @@ test "implicit cast fn call result to optional in field result" {...@@ -250,3 +250,101 @@ test "implicit cast fn call result to optional in field result" {
250 try S.entry();250 try S.entry();
251 comptime try S.entry();251 comptime try S.entry();
252}252}
253
254test "void parameters" {
255 try voidFun(1, void{}, 2, {});
256}
257fn voidFun(a: i32, b: void, c: i32, d: void) !void {
258 _ = d;
259 const v = b;
260 const vv: void = if (a == 1) v else {};
261 try expect(a + c == 3);
262 return vv;
263}
264
265test "call function with empty string" {
266 acceptsString("");
267}
268
269fn acceptsString(foo: []u8) void {
270 _ = foo;
271}
272
273test "function pointers" {
274 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
275
276 const fns = [_]@TypeOf(fn1){
277 fn1,
278 fn2,
279 fn3,
280 fn4,
281 };
282 for (fns) |f, i| {
283 try expect(f() == @intCast(u32, i) + 5);
284 }
285}
286fn fn1() u32 {
287 return 5;
288}
289fn fn2() u32 {
290 return 6;
291}
292fn fn3() u32 {
293 return 7;
294}
295fn fn4() u32 {
296 return 8;
297}
298
299test "number literal as an argument" {
300 try numberLiteralArg(3);
301 comptime try numberLiteralArg(3);
302}
303
304fn numberLiteralArg(a: anytype) !void {
305 try expect(a == 3);
306}
307
308test "function call with anon list literal" {
309 const S = struct {
310 fn doTheTest() !void {
311 try consumeVec(.{ 9, 8, 7 });
312 }
313
314 fn consumeVec(vec: [3]f32) !void {
315 try expect(vec[0] == 9);
316 try expect(vec[1] == 8);
317 try expect(vec[2] == 7);
318 }
319 };
320 try S.doTheTest();
321 comptime try S.doTheTest();
322}
323
324test "ability to give comptime types and non comptime types to same parameter" {
325 const S = struct {
326 fn doTheTest() !void {
327 var x: i32 = 1;
328 try expect(foo(x) == 10);
329 try expect(foo(i32) == 20);
330 }
331
332 fn foo(arg: anytype) i32 {
333 if (@typeInfo(@TypeOf(arg)) == .Type and arg == i32) return 20;
334 return 9 + arg;
335 }
336 };
337 try S.doTheTest();
338 comptime try S.doTheTest();
339}
340
341test "function with inferred error set but returning no error" {
342 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
343
344 const S = struct {
345 fn foo() !void {}
346 };
347
348 const return_ty = @typeInfo(@TypeOf(S.foo)).Fn.return_type.?;
349 try expectEqual(0, @typeInfo(@typeInfo(return_ty).ErrorUnion.error_set).ErrorSet.?.len);
350}
test/behavior/fn_stage1.zig deleted-99
...@@ -1,99 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const testing = std.testing;
4const expect = testing.expect;
5const expectEqual = testing.expectEqual;
6
7test "void parameters" {
8 try voidFun(1, void{}, 2, {});
9}
10fn voidFun(a: i32, b: void, c: i32, d: void) !void {
11 _ = d;
12 const v = b;
13 const vv: void = if (a == 1) v else {};
14 try expect(a + c == 3);
15 return vv;
16}
17
18test "call function with empty string" {
19 acceptsString("");
20}
21
22fn acceptsString(foo: []u8) void {
23 _ = foo;
24}
25
26test "function pointers" {
27 const fns = [_]@TypeOf(fn1){
28 fn1,
29 fn2,
30 fn3,
31 fn4,
32 };
33 for (fns) |f, i| {
34 try expect(f() == @intCast(u32, i) + 5);
35 }
36}
37fn fn1() u32 {
38 return 5;
39}
40fn fn2() u32 {
41 return 6;
42}
43fn fn3() u32 {
44 return 7;
45}
46fn fn4() u32 {
47 return 8;
48}
49
50test "number literal as an argument" {
51 try numberLiteralArg(3);
52 comptime try numberLiteralArg(3);
53}
54
55fn numberLiteralArg(a: anytype) !void {
56 try expect(a == 3);
57}
58
59test "function call with anon list literal" {
60 const S = struct {
61 fn doTheTest() !void {
62 try consumeVec(.{ 9, 8, 7 });
63 }
64
65 fn consumeVec(vec: [3]f32) !void {
66 try expect(vec[0] == 9);
67 try expect(vec[1] == 8);
68 try expect(vec[2] == 7);
69 }
70 };
71 try S.doTheTest();
72 comptime try S.doTheTest();
73}
74
75test "ability to give comptime types and non comptime types to same parameter" {
76 const S = struct {
77 fn doTheTest() !void {
78 var x: i32 = 1;
79 try expect(foo(x) == 10);
80 try expect(foo(i32) == 20);
81 }
82
83 fn foo(arg: anytype) i32 {
84 if (@typeInfo(@TypeOf(arg)) == .Type and arg == i32) return 20;
85 return 9 + arg;
86 }
87 };
88 try S.doTheTest();
89 comptime try S.doTheTest();
90}
91
92test "function with inferred error set but returning no error" {
93 const S = struct {
94 fn foo() !void {}
95 };
96
97 const return_ty = @typeInfo(@TypeOf(S.foo)).Fn.return_type.?;
98 try expectEqual(0, @typeInfo(@typeInfo(return_ty).ErrorUnion.error_set).ErrorSet.?.len);
99}
test/behavior/for.zig+57
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("std");2const std = @import("std");
2const expect = std.testing.expect;3const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;4const expectEqual = std.testing.expectEqual;
...@@ -133,3 +134,59 @@ test "2 break statements and an else" {...@@ -133,3 +134,59 @@ test "2 break statements and an else" {
133 try S.entry(true, false);134 try S.entry(true, false);
134 comptime try S.entry(true, false);135 comptime try S.entry(true, false);
135}136}
137
138test "for loop with pointer elem var" {
139 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
140
141 const source = "abcdefg";
142 var target: [source.len]u8 = undefined;
143 mem.copy(u8, target[0..], source);
144 mangleString(target[0..]);
145 try expect(mem.eql(u8, &target, "bcdefgh"));
146
147 for (source) |*c, i| {
148 _ = i;
149 try expect(@TypeOf(c) == *const u8);
150 }
151 for (target) |*c, i| {
152 _ = i;
153 try expect(@TypeOf(c) == *u8);
154 }
155}
156
157fn mangleString(s: []u8) void {
158 for (s) |*c| {
159 c.* += 1;
160 }
161}
162
163test "for copies its payload" {
164 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
165
166 const S = struct {
167 fn doTheTest() !void {
168 var x = [_]usize{ 1, 2, 3 };
169 for (x) |value, i| {
170 // Modify the original array
171 x[i] += 99;
172 try expectEqual(value, i + 1);
173 }
174 }
175 };
176 try S.doTheTest();
177 comptime try S.doTheTest();
178}
179
180test "for on slice with allowzero ptr" {
181 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
182
183 const S = struct {
184 fn doTheTest(slice: []const u8) !void {
185 var ptr = @ptrCast([*]allowzero const u8, slice.ptr)[0..slice.len];
186 for (ptr) |x, i| try expect(x == i + 1);
187 for (ptr) |*x, i| try expect(x.* == i + 1);
188 }
189 };
190 try S.doTheTest(&[_]u8{ 1, 2, 3, 4 });
191 comptime try S.doTheTest(&[_]u8{ 1, 2, 3, 4 });
192}
test/behavior/for_stage1.zig deleted-54
...@@ -1,54 +0,0 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;
4const mem = std.mem;
5
6test "for loop with pointer elem var" {
7 const source = "abcdefg";
8 var target: [source.len]u8 = undefined;
9 mem.copy(u8, target[0..], source);
10 mangleString(target[0..]);
11 try expect(mem.eql(u8, &target, "bcdefgh"));
12
13 for (source) |*c, i| {
14 _ = i;
15 try expect(@TypeOf(c) == *const u8);
16 }
17 for (target) |*c, i| {
18 _ = i;
19 try expect(@TypeOf(c) == *u8);
20 }
21}
22
23fn mangleString(s: []u8) void {
24 for (s) |*c| {
25 c.* += 1;
26 }
27}
28
29test "for copies its payload" {
30 const S = struct {
31 fn doTheTest() !void {
32 var x = [_]usize{ 1, 2, 3 };
33 for (x) |value, i| {
34 // Modify the original array
35 x[i] += 99;
36 try expectEqual(value, i + 1);
37 }
38 }
39 };
40 try S.doTheTest();
41 comptime try S.doTheTest();
42}
43
44test "for on slice with allowzero ptr" {
45 const S = struct {
46 fn doTheTest(slice: []const u8) !void {
47 var ptr = @ptrCast([*]allowzero const u8, slice.ptr)[0..slice.len];
48 for (ptr) |x, i| try expect(x == i + 1);
49 for (ptr) |*x, i| try expect(x.* == i + 1);
50 }
51 };
52 try S.doTheTest(&[_]u8{ 1, 2, 3, 4 });
53 comptime try S.doTheTest(&[_]u8{ 1, 2, 3, 4 });
54}
test/behavior/if.zig+19
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("std");2const std = @import("std");
2const expect = std.testing.expect;3const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;4const expectEqual = std.testing.expectEqual;
...@@ -88,3 +89,21 @@ test "if copies its payload" {...@@ -88,3 +89,21 @@ test "if copies its payload" {
88 try S.doTheTest();89 try S.doTheTest();
89 comptime try S.doTheTest();90 comptime try S.doTheTest();
90}91}
92
93test "if prongs cast to expected type instead of peer type resolution" {
94 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
95
96 const S = struct {
97 fn doTheTest(f: bool) !void {
98 var x: i32 = 0;
99 x = if (f) 1 else 2;
100 try expect(x == 2);
101
102 var b = true;
103 const y: i32 = if (b) 1 else 2;
104 try expect(y == 1);
105 }
106 };
107 try S.doTheTest(false);
108 comptime try S.doTheTest(false);
109}
test/behavior/if_stage1.zig deleted-19
...@@ -1,19 +0,0 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;
4
5test "if prongs cast to expected type instead of peer type resolution" {
6 const S = struct {
7 fn doTheTest(f: bool) !void {
8 var x: i32 = 0;
9 x = if (f) 1 else 2;
10 try expect(x == 2);
11
12 var b = true;
13 const y: i32 = if (b) 1 else 2;
14 try expect(y == 1);
15 }
16 };
17 try S.doTheTest(false);
18 comptime try S.doTheTest(false);
19}
test/behavior/misc.zig-130
...@@ -5,63 +5,6 @@ const expectEqualStrings = std.testing.expectEqualStrings;...@@ -5,63 +5,6 @@ const expectEqualStrings = std.testing.expectEqualStrings;
5const mem = std.mem;5const mem = std.mem;
6const builtin = @import("builtin");6const builtin = @import("builtin");
77
8fn emptyFn() void {}
9
10const addr1 = @ptrCast(*const u8, emptyFn);
11test "comptime cast fn to ptr" {
12 const addr2 = @ptrCast(*const u8, emptyFn);
13 comptime try expect(addr1 == addr2);
14}
15
16test "equality compare fn ptrs" {
17 var a = emptyFn;
18 try expect(a == a);
19}
20
21test "string escapes" {
22 try expectEqualStrings("\"", "\x22");
23 try expectEqualStrings("\'", "\x27");
24 try expectEqualStrings("\n", "\x0a");
25 try expectEqualStrings("\r", "\x0d");
26 try expectEqualStrings("\t", "\x09");
27 try expectEqualStrings("\\", "\x5c");
28 try expectEqualStrings("\u{1234}\u{069}\u{1}", "\xe1\x88\xb4\x69\x01");
29}
30
31test "explicit cast optional pointers" {
32 const a: ?*i32 = undefined;
33 const b: ?*f32 = @ptrCast(?*f32, a);
34 _ = b;
35}
36
37test "pointer comparison" {
38 const a = @as([]const u8, "a");
39 const b = &a;
40 try expect(ptrEql(b, b));
41}
42fn ptrEql(a: *const []const u8, b: *const []const u8) bool {
43 return a == b;
44}
45
46test "string concatenation" {
47 const a = "OK" ++ " IT " ++ "WORKED";
48 const b = "OK IT WORKED";
49
50 comptime try expect(@TypeOf(a) == *const [12:0]u8);
51 comptime try expect(@TypeOf(b) == *const [12:0]u8);
52
53 const len = mem.len(b);
54 const len_with_null = len + 1;
55 {
56 var i: u32 = 0;
57 while (i < len_with_null) : (i += 1) {
58 try expect(a[i] == b[i]);
59 }
60 }
61 try expect(a[len] == 0);
62 try expect(b[len] == 0);
63}
64
65// can't really run this test but we can make sure it has no compile error8// can't really run this test but we can make sure it has no compile error
66// and generates code9// and generates code
67const vram = @intToPtr([*]volatile u8, 0x20000000)[0..0x8000];10const vram = @intToPtr([*]volatile u8, 0x20000000)[0..0x8000];
...@@ -91,76 +34,3 @@ export fn testPackedStuff(a: *const PackedStruct, b: *const PackedUnion) void {...@@ -91,76 +34,3 @@ export fn testPackedStuff(a: *const PackedStruct, b: *const PackedUnion) void {
91 b;34 b;
92 }35 }
93}36}
94
95test "thread local variable" {
96 const S = struct {
97 threadlocal var t: i32 = 1234;
98 };
99 S.t += 1;
100 try expect(S.t == 1235);
101}
102
103fn maybe(x: bool) anyerror!?u32 {
104 return switch (x) {
105 true => @as(u32, 42),
106 else => null,
107 };
108}
109
110test "result location is optional inside error union" {
111 const x = maybe(true) catch unreachable;
112 try expect(x.? == 42);
113}
114
115threadlocal var buffer: [11]u8 = undefined;
116
117test "pointer to thread local array" {
118 const s = "Hello world";
119 std.mem.copy(u8, buffer[0..], s);
120 try std.testing.expectEqualSlices(u8, buffer[0..], s);
121}
122
123test "auto created variables have correct alignment" {
124 const S = struct {
125 fn foo(str: [*]const u8) u32 {
126 for (@ptrCast([*]align(1) const u32, str)[0..1]) |v| {
127 return v;
128 }
129 return 0;
130 }
131 };
132 try expect(S.foo("\x7a\x7a\x7a\x7a") == 0x7a7a7a7a);
133 comptime try expect(S.foo("\x7a\x7a\x7a\x7a") == 0x7a7a7a7a);
134}
135
136extern var opaque_extern_var: opaque {};
137var var_to_export: u32 = 42;
138test "extern variable with non-pointer opaque type" {
139 @export(var_to_export, .{ .name = "opaque_extern_var" });
140 try expect(@ptrCast(*align(1) u32, &opaque_extern_var).* == 42);
141}
142
143test "lazy typeInfo value as generic parameter" {
144 const S = struct {
145 fn foo(args: anytype) void {
146 _ = args;
147 }
148 };
149 S.foo(@typeInfo(@TypeOf(.{})));
150}
151
152test "variable name containing underscores does not shadow int primitive" {
153 const _u0 = 0;
154 const i_8 = 0;
155 const u16_ = 0;
156 const i3_2 = 0;
157 const u6__4 = 0;
158 const i2_04_8 = 0;
159
160 _ = _u0;
161 _ = i_8;
162 _ = u16_;
163 _ = i3_2;
164 _ = u6__4;
165 _ = i2_04_8;
166}