authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-10-13 21:43:19-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-10-13 21:43:19-07:00
loged5a5e22936e5d90b6c9d255b17076f0db45c040
tree2fbb7435c4595de93277d0341373ba1ffd1982e4
parent0d4a94f32fc71f81d54db038f013854b8e9f0ac4

move behavior tests that are passing for stage2


6 files changed, 550 insertions(+), 531 deletions(-)

test/behavior.zig+2-1
......@@ -25,6 +25,7 @@ test {
2525 _ = @import("behavior/if.zig");
2626 _ = @import("behavior/math.zig");
2727 _ = @import("behavior/member_func.zig");
28 _ = @import("behavior/optional.zig");
2829 _ = @import("behavior/pointers.zig");
2930 _ = @import("behavior/slice.zig");
3031 _ = @import("behavior/sizeof_and_typeof.zig");
......@@ -135,7 +136,7 @@ test {
135136 _ = @import("behavior/muladd.zig");
136137 _ = @import("behavior/namespace_depends_on_compile_var.zig");
137138 _ = @import("behavior/null.zig");
138 _ = @import("behavior/optional.zig");
139 _ = @import("behavior/optional_stage1.zig");
139140 _ = @import("behavior/pointers_stage1.zig");
140141 _ = @import("behavior/popcount.zig");
141142 _ = @import("behavior/ptrcast.zig");
test/behavior/basic.zig+211
......@@ -1,4 +1,5 @@
11const std = @import("std");
2const builtin = @import("builtin");
23const mem = std.mem;
34const expect = std.testing.expect;
45
......@@ -192,6 +193,14 @@ fn testMemcpyMemset() !void {
192193const OpaqueA = opaque {};
193194const OpaqueB = opaque {};
194195
196test "opaque types" {
197 try expect(*OpaqueA != *OpaqueB);
198 if (!builtin.zig_is_stage2) {
199 try expect(mem.eql(u8, @typeName(OpaqueA), "OpaqueA"));
200 try expect(mem.eql(u8, @typeName(OpaqueB), "OpaqueB"));
201 }
202}
203
195204test "variable is allowed to be a pointer to an opaque type" {
196205 var x: i32 = 1234;
197206 _ = hereIsAnOpaqueType(@ptrCast(*OpaqueA, &x));
......@@ -200,3 +209,205 @@ fn hereIsAnOpaqueType(ptr: *OpaqueA) *OpaqueA {
200209 var a = ptr;
201210 return a;
202211}
212
213const global_a: i32 = 1234;
214const global_b: *const i32 = &global_a;
215const global_c: *const f32 = @ptrCast(*const f32, global_b);
216test "compile time global reinterpret" {
217 const d = @ptrCast(*const i32, global_c);
218 try expect(d.* == 1234);
219}
220
221test "cast undefined" {
222 const array: [100]u8 = undefined;
223 const slice = @as([]const u8, &array);
224 testCastUndefined(slice);
225}
226fn testCastUndefined(x: []const u8) void {
227 _ = x;
228}
229
230test "implicit cast after unreachable" {
231 try expect(outer() == 1234);
232}
233fn inner() i32 {
234 return 1234;
235}
236fn outer() i64 {
237 return inner();
238}
239
240test "take address of parameter" {
241 try testTakeAddressOfParameter(12.34);
242}
243fn testTakeAddressOfParameter(f: f32) !void {
244 const f_ptr = &f;
245 try expect(f_ptr.* == 12.34);
246}
247
248test "pointer to void return type" {
249 testPointerToVoidReturnType() catch unreachable;
250}
251fn testPointerToVoidReturnType() anyerror!void {
252 const a = testPointerToVoidReturnType2();
253 return a.*;
254}
255const test_pointer_to_void_return_type_x = void{};
256fn testPointerToVoidReturnType2() *const void {
257 return &test_pointer_to_void_return_type_x;
258}
259
260test "array 2D const double ptr" {
261 const rect_2d_vertexes = [_][1]f32{
262 [_]f32{1.0},
263 [_]f32{2.0},
264 };
265 try testArray2DConstDoublePtr(&rect_2d_vertexes[0][0]);
266}
267
268fn testArray2DConstDoublePtr(ptr: *const f32) !void {
269 const ptr2 = @ptrCast([*]const f32, ptr);
270 try expect(ptr2[0] == 1.0);
271 try expect(ptr2[1] == 2.0);
272}
273
274test "double implicit cast in same expression" {
275 var x = @as(i32, @as(u16, nine()));
276 try expect(x == 9);
277}
278fn nine() u8 {
279 return 9;
280}
281
282test "comptime if inside runtime while which unconditionally breaks" {
283 testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true);
284 comptime testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true);
285}
286fn testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(cond: bool) void {
287 while (cond) {
288 if (false) {}
289 break;
290 }
291}
292
293test "implicit comptime while" {
294 while (false) {
295 @compileError("bad");
296 }
297}
298
299fn fnThatClosesOverLocalConst() type {
300 const c = 1;
301 return struct {
302 fn g() i32 {
303 return c;
304 }
305 };
306}
307
308test "function closes over local const" {
309 const x = fnThatClosesOverLocalConst().g();
310 try expect(x == 1);
311}
312
313test "volatile load and store" {
314 var number: i32 = 1234;
315 const ptr = @as(*volatile i32, &number);
316 ptr.* += 1;
317 try expect(ptr.* == 1235);
318}
319
320test "struct inside function" {
321 try testStructInFn();
322 comptime try testStructInFn();
323}
324
325fn testStructInFn() !void {
326 const BlockKind = u32;
327
328 const Block = struct {
329 kind: BlockKind,
330 };
331
332 var block = Block{ .kind = 1234 };
333
334 block.kind += 1;
335
336 try expect(block.kind == 1235);
337}
338
339test "fn call returning scalar optional in equality expression" {
340 try expect(getNull() == null);
341}
342
343fn getNull() ?*i32 {
344 return null;
345}
346
347var global_foo: *i32 = undefined;
348
349test "global variable assignment with optional unwrapping with var initialized to undefined" {
350 const S = struct {
351 var data: i32 = 1234;
352 fn foo() ?*i32 {
353 return &data;
354 }
355 };
356 global_foo = S.foo() orelse {
357 @panic("bad");
358 };
359 try expect(global_foo.* == 1234);
360}
361
362test "peer result location with typed parent, runtime condition, comptime prongs" {
363 const S = struct {
364 fn doTheTest(arg: i32) i32 {
365 const st = Structy{
366 .bleh = if (arg == 1) 1 else 1,
367 };
368
369 if (st.bleh == 1)
370 return 1234;
371 return 0;
372 }
373
374 const Structy = struct {
375 bleh: i32,
376 };
377 };
378 try expect(S.doTheTest(0) == 1234);
379 try expect(S.doTheTest(1) == 1234);
380}
381
382fn ZA() type {
383 return struct {
384 b: B(),
385
386 const Self = @This();
387
388 fn B() type {
389 return struct {
390 const Self = @This();
391 };
392 }
393 };
394}
395test "non-ambiguous reference of shadowed decls" {
396 try expect(ZA().B().Self != ZA().Self);
397}
398
399test "use of declaration with same name as primitive" {
400 const S = struct {
401 const @"u8" = u16;
402 const alias = @"u8";
403 };
404 const a: S.u8 = 300;
405 try expect(a == 300);
406
407 const b: S.alias = 300;
408 try expect(b == 300);
409
410 const @"u8" = u16;
411 const c: @"u8" = 300;
412 try expect(c == 300);
413}
test/behavior/misc.zig+12-263
......@@ -5,6 +5,8 @@ const expectEqualStrings = std.testing.expectEqualStrings;
55const mem = std.mem;
66const builtin = @import("builtin");
77
8fn emptyFn() void {}
9
810test "constant equal function pointers" {
911 const alias = emptyFn;
1012 try expect(comptime x: {
......@@ -12,7 +14,16 @@ test "constant equal function pointers" {
1214 });
1315}
1416
15fn emptyFn() void {}
17const addr1 = @ptrCast(*const u8, emptyFn);
18test "comptime cast fn to ptr" {
19 const addr2 = @ptrCast(*const u8, emptyFn);
20 comptime try expect(addr1 == addr2);
21}
22
23test "equality compare fn ptrs" {
24 var a = emptyFn;
25 try expect(a == a);
26}
1627
1728test "string escapes" {
1829 try expectEqualStrings("\"", "\x22");
......@@ -34,51 +45,12 @@ test "multiline string literal is null terminated" {
3445 try expect(std.cstr.cmp(s1, s2) == 0);
3546}
3647
37const global_a: i32 = 1234;
38const global_b: *const i32 = &global_a;
39const global_c: *const f32 = @ptrCast(*const f32, global_b);
40test "compile time global reinterpret" {
41 const d = @ptrCast(*const i32, global_c);
42 try expect(d.* == 1234);
43}
44
4548test "explicit cast maybe pointers" {
4649 const a: ?*i32 = undefined;
4750 const b: ?*f32 = @ptrCast(?*f32, a);
4851 _ = b;
4952}
5053
51test "generic malloc free" {
52 const a = memAlloc(u8, 10) catch unreachable;
53 memFree(u8, a);
54}
55var some_mem: [100]u8 = undefined;
56fn memAlloc(comptime T: type, n: usize) anyerror![]T {
57 return @ptrCast([*]T, &some_mem[0])[0..n];
58}
59fn memFree(comptime T: type, memory: []T) void {
60 _ = memory;
61}
62
63test "cast undefined" {
64 const array: [100]u8 = undefined;
65 const slice = @as([]const u8, &array);
66 testCastUndefined(slice);
67}
68fn testCastUndefined(x: []const u8) void {
69 _ = x;
70}
71
72test "implicit cast after unreachable" {
73 try expect(outer() == 1234);
74}
75fn inner() i32 {
76 return 1234;
77}
78fn outer() i64 {
79 return inner();
80}
81
8254test "constant enum initialization with differing sizes" {
8355 try test3_1(test3_foo);
8456 try test3_2(test3_bar);
......@@ -117,14 +89,6 @@ fn test3_2(f: Test3Foo) !void {
11789 }
11890}
11991
120test "take address of parameter" {
121 try testTakeAddressOfParameter(12.34);
122}
123fn testTakeAddressOfParameter(f: f32) !void {
124 const f_ptr = &f;
125 try expect(f_ptr.* == 12.34);
126}
127
12892test "pointer comparison" {
12993 const a = @as([]const u8, "a");
13094 const b = &a;
......@@ -153,40 +117,6 @@ test "string concatenation" {
153117 try expect(b[len] == 0);
154118}
155119
156test "pointer to void return type" {
157 testPointerToVoidReturnType() catch unreachable;
158}
159fn testPointerToVoidReturnType() anyerror!void {
160 const a = testPointerToVoidReturnType2();
161 return a.*;
162}
163const test_pointer_to_void_return_type_x = void{};
164fn testPointerToVoidReturnType2() *const void {
165 return &test_pointer_to_void_return_type_x;
166}
167
168test "array 2D const double ptr" {
169 const rect_2d_vertexes = [_][1]f32{
170 [_]f32{1.0},
171 [_]f32{2.0},
172 };
173 try testArray2DConstDoublePtr(&rect_2d_vertexes[0][0]);
174}
175
176fn testArray2DConstDoublePtr(ptr: *const f32) !void {
177 const ptr2 = @ptrCast([*]const f32, ptr);
178 try expect(ptr2[0] == 1.0);
179 try expect(ptr2[1] == 2.0);
180}
181
182test "double implicit cast in same expression" {
183 var x = @as(i32, @as(u16, nine()));
184 try expect(x == 9);
185}
186fn nine() u8 {
187 return 9;
188}
189
190120test "global variable initialized to global variable array element" {
191121 try expect(global_ptr == &gdt[0]);
192122}
......@@ -206,45 +136,6 @@ export fn writeToVRam() void {
206136 vram[0] = 'X';
207137}
208138
209const OpaqueA = opaque {};
210const OpaqueB = opaque {};
211test "opaque types" {
212 try expect(*OpaqueA != *OpaqueB);
213 try expect(mem.eql(u8, @typeName(OpaqueA), "OpaqueA"));
214 try expect(mem.eql(u8, @typeName(OpaqueB), "OpaqueB"));
215}
216
217test "comptime if inside runtime while which unconditionally breaks" {
218 testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true);
219 comptime testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true);
220}
221fn testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(cond: bool) void {
222 while (cond) {
223 if (false) {}
224 break;
225 }
226}
227
228test "implicit comptime while" {
229 while (false) {
230 @compileError("bad");
231 }
232}
233
234fn fnThatClosesOverLocalConst() type {
235 const c = 1;
236 return struct {
237 fn g() i32 {
238 return c;
239 }
240 };
241}
242
243test "function closes over local const" {
244 const x = fnThatClosesOverLocalConst().g();
245 try expect(x == 1);
246}
247
248139const PackedStruct = packed struct {
249140 a: u8,
250141 b: u8,
......@@ -268,26 +159,6 @@ export fn testPackedStuff(a: *const PackedStruct, b: *const PackedUnion) void {
268159 }
269160}
270161
271test "slicing zero length array" {
272 const s1 = ""[0..];
273 const s2 = ([_]u32{})[0..];
274 try expect(s1.len == 0);
275 try expect(s2.len == 0);
276 try expect(mem.eql(u8, s1, ""));
277 try expect(mem.eql(u32, s2, &[_]u32{}));
278}
279
280const addr1 = @ptrCast(*const u8, emptyFn);
281test "comptime cast fn to ptr" {
282 const addr2 = @ptrCast(*const u8, emptyFn);
283 comptime try expect(addr1 == addr2);
284}
285
286test "equality compare fn ptrs" {
287 var a = emptyFn;
288 try expect(a == a);
289}
290
291162test "self reference through fn ptr field" {
292163 const S = struct {
293164 const A = struct {
......@@ -304,52 +175,6 @@ test "self reference through fn ptr field" {
304175 try expect(a.f(a) == 12);
305176}
306177
307test "volatile load and store" {
308 var number: i32 = 1234;
309 const ptr = @as(*volatile i32, &number);
310 ptr.* += 1;
311 try expect(ptr.* == 1235);
312}
313
314test "slice string literal has correct type" {
315 comptime {
316 try expect(@TypeOf("aoeu"[0..]) == *const [4:0]u8);
317 const array = [_]i32{ 1, 2, 3, 4 };
318 try expect(@TypeOf(array[0..]) == *const [4]i32);
319 }
320 var runtime_zero: usize = 0;
321 comptime try expect(@TypeOf("aoeu"[runtime_zero..]) == [:0]const u8);
322 const array = [_]i32{ 1, 2, 3, 4 };
323 comptime try expect(@TypeOf(array[runtime_zero..]) == []const i32);
324}
325
326test "struct inside function" {
327 try testStructInFn();
328 comptime try testStructInFn();
329}
330
331fn testStructInFn() !void {
332 const BlockKind = u32;
333
334 const Block = struct {
335 kind: BlockKind,
336 };
337
338 var block = Block{ .kind = 1234 };
339
340 block.kind += 1;
341
342 try expect(block.kind == 1235);
343}
344
345test "fn call returning scalar optional in equality expression" {
346 try expect(getNull() == null);
347}
348
349fn getNull() ?*i32 {
350 return null;
351}
352
353178test "thread local variable" {
354179 const S = struct {
355180 threadlocal var t: i32 = 1234;
......@@ -358,49 +183,6 @@ test "thread local variable" {
358183 try expect(S.t == 1235);
359184}
360185
361test "result location zero sized array inside struct field implicit cast to slice" {
362 const E = struct {
363 entries: []u32,
364 };
365 var foo = E{ .entries = &[_]u32{} };
366 try expect(foo.entries.len == 0);
367}
368
369var global_foo: *i32 = undefined;
370
371test "global variable assignment with optional unwrapping with var initialized to undefined" {
372 const S = struct {
373 var data: i32 = 1234;
374 fn foo() ?*i32 {
375 return &data;
376 }
377 };
378 global_foo = S.foo() orelse {
379 @panic("bad");
380 };
381 try expect(global_foo.* == 1234);
382}
383
384test "peer result location with typed parent, runtime condition, comptime prongs" {
385 const S = struct {
386 fn doTheTest(arg: i32) i32 {
387 const st = Structy{
388 .bleh = if (arg == 1) 1 else 1,
389 };
390
391 if (st.bleh == 1)
392 return 1234;
393 return 0;
394 }
395
396 const Structy = struct {
397 bleh: i32,
398 };
399 };
400 try expect(S.doTheTest(0) == 1234);
401 try expect(S.doTheTest(1) == 1234);
402}
403
404186test "nested optional field in struct" {
405187 const S2 = struct {
406188 y: u8,
......@@ -462,36 +244,3 @@ test "lazy typeInfo value as generic parameter" {
462244 };
463245 S.foo(@typeInfo(@TypeOf(.{})));
464246}
465
466fn ZA() type {
467 return struct {
468 b: B(),
469
470 const Self = @This();
471
472 fn B() type {
473 return struct {
474 const Self = @This();
475 };
476 }
477 };
478}
479test "non-ambiguous reference of shadowed decls" {
480 try expect(ZA().B().Self != ZA().Self);
481}
482
483test "use of declaration with same name as primitive" {
484 const S = struct {
485 const @"u8" = u16;
486 const alias = @"u8";
487 };
488 const a: S.u8 = 300;
489 try expect(a == 300);
490
491 const b: S.alias = 300;
492 try expect(b == 300);
493
494 const @"u8" = u16;
495 const c: @"u8" = 300;
496 try expect(c == 300);
497}
test/behavior/optional.zig-267
......@@ -2,270 +2,3 @@ const std = @import("std");
22const testing = std.testing;
33const expect = testing.expect;
44const expectEqual = testing.expectEqual;
5
6pub const EmptyStruct = struct {};
7
8test "optional pointer to size zero struct" {
9 var e = EmptyStruct{};
10 var o: ?*EmptyStruct = &e;
11 try expect(o != null);
12}
13
14test "equality compare nullable pointers" {
15 try testNullPtrsEql();
16 comptime try testNullPtrsEql();
17}
18
19fn testNullPtrsEql() !void {
20 var number: i32 = 1234;
21
22 var x: ?*i32 = null;
23 var y: ?*i32 = null;
24 try expect(x == y);
25 y = &number;
26 try expect(x != y);
27 try expect(x != &number);
28 try expect(&number != x);
29 x = &number;
30 try expect(x == y);
31 try expect(x == &number);
32 try expect(&number == x);
33}
34
35test "address of unwrap optional" {
36 const S = struct {
37 const Foo = struct {
38 a: i32,
39 };
40
41 var global: ?Foo = null;
42
43 pub fn getFoo() anyerror!*Foo {
44 return &global.?;
45 }
46 };
47 S.global = S.Foo{ .a = 1234 };
48 const foo = S.getFoo() catch unreachable;
49 try expect(foo.a == 1234);
50}
51
52test "equality compare optional with non-optional" {
53 try test_cmp_optional_non_optional();
54 comptime try test_cmp_optional_non_optional();
55}
56
57fn test_cmp_optional_non_optional() !void {
58 var ten: i32 = 10;
59 var opt_ten: ?i32 = 10;
60 var five: i32 = 5;
61 var int_n: ?i32 = null;
62
63 try expect(int_n != ten);
64 try expect(opt_ten == ten);
65 try expect(opt_ten != five);
66
67 // test evaluation is always lexical
68 // ensure that the optional isn't always computed before the non-optional
69 var mutable_state: i32 = 0;
70 _ = blk1: {
71 mutable_state += 1;
72 break :blk1 @as(?f64, 10.0);
73 } != blk2: {
74 try expect(mutable_state == 1);
75 break :blk2 @as(f64, 5.0);
76 };
77 _ = blk1: {
78 mutable_state += 1;
79 break :blk1 @as(f64, 10.0);
80 } != blk2: {
81 try expect(mutable_state == 2);
82 break :blk2 @as(?f64, 5.0);
83 };
84}
85
86test "passing an optional integer as a parameter" {
87 const S = struct {
88 fn entry() bool {
89 var x: i32 = 1234;
90 return foo(x);
91 }
92
93 fn foo(x: ?i32) bool {
94 return x.? == 1234;
95 }
96 };
97 try expect(S.entry());
98 comptime try expect(S.entry());
99}
100
101test "unwrap function call with optional pointer return value" {
102 const S = struct {
103 fn entry() !void {
104 try expect(foo().?.* == 1234);
105 try expect(bar() == null);
106 }
107 const global: i32 = 1234;
108 fn foo() ?*const i32 {
109 return &global;
110 }
111 fn bar() ?*i32 {
112 return null;
113 }
114 };
115 try S.entry();
116 comptime try S.entry();
117}
118
119test "nested orelse" {
120 const S = struct {
121 fn entry() !void {
122 try expect(func() == null);
123 }
124 fn maybe() ?Foo {
125 return null;
126 }
127 fn func() ?Foo {
128 const x = maybe() orelse
129 maybe() orelse
130 return null;
131 _ = x;
132 unreachable;
133 }
134 const Foo = struct {
135 field: i32,
136 };
137 };
138 try S.entry();
139 comptime try S.entry();
140}
141
142test "self-referential struct through a slice of optional" {
143 const S = struct {
144 const Node = struct {
145 children: []?Node,
146 data: ?u8,
147
148 fn new() Node {
149 return Node{
150 .children = undefined,
151 .data = null,
152 };
153 }
154 };
155 };
156
157 var n = S.Node.new();
158 try expect(n.data == null);
159}
160
161test "assigning to an unwrapped optional field in an inline loop" {
162 comptime var maybe_pos_arg: ?comptime_int = null;
163 inline for ("ab") |x| {
164 _ = x;
165 maybe_pos_arg = 0;
166 if (maybe_pos_arg.? != 0) {
167 @compileError("bad");
168 }
169 maybe_pos_arg.? = 10;
170 }
171}
172
173test "coerce an anon struct literal to optional struct" {
174 const S = struct {
175 const Struct = struct {
176 field: u32,
177 };
178 fn doTheTest() !void {
179 var maybe_dims: ?Struct = null;
180 maybe_dims = .{ .field = 1 };
181 try expect(maybe_dims.?.field == 1);
182 }
183 };
184 try S.doTheTest();
185 comptime try S.doTheTest();
186}
187
188test "optional with void type" {
189 const Foo = struct {
190 x: ?void,
191 };
192 var x = Foo{ .x = null };
193 try expect(x.x == null);
194}
195
196test "0-bit child type coerced to optional return ptr result location" {
197 const S = struct {
198 fn doTheTest() !void {
199 var y = Foo{};
200 var z = y.thing();
201 try expect(z != null);
202 }
203
204 const Foo = struct {
205 pub const Bar = struct {
206 field: *Foo,
207 };
208
209 pub fn thing(self: *Foo) ?Bar {
210 return Bar{ .field = self };
211 }
212 };
213 };
214 try S.doTheTest();
215 comptime try S.doTheTest();
216}
217
218test "0-bit child type coerced to optional" {
219 const S = struct {
220 fn doTheTest() !void {
221 var it: Foo = .{
222 .list = undefined,
223 };
224 try expect(it.foo() != null);
225 }
226
227 const Empty = struct {};
228 const Foo = struct {
229 list: [10]Empty,
230
231 fn foo(self: *Foo) ?*Empty {
232 const data = &self.list[0];
233 return data;
234 }
235 };
236 };
237 try S.doTheTest();
238 comptime try S.doTheTest();
239}
240
241test "array of optional unaligned types" {
242 const Enum = enum { one, two, three };
243
244 const SomeUnion = union(enum) {
245 Num: Enum,
246 Other: u32,
247 };
248
249 const values = [_]?SomeUnion{
250 SomeUnion{ .Num = .one },
251 SomeUnion{ .Num = .two },
252 SomeUnion{ .Num = .three },
253 SomeUnion{ .Num = .one },
254 SomeUnion{ .Num = .two },
255 SomeUnion{ .Num = .three },
256 };
257
258 // The index must be a runtime value
259 var i: usize = 0;
260 try expectEqual(Enum.one, values[i].?.Num);
261 i += 1;
262 try expectEqual(Enum.two, values[i].?.Num);
263 i += 1;
264 try expectEqual(Enum.three, values[i].?.Num);
265 i += 1;
266 try expectEqual(Enum.one, values[i].?.Num);
267 i += 1;
268 try expectEqual(Enum.two, values[i].?.Num);
269 i += 1;
270 try expectEqual(Enum.three, values[i].?.Num);
271}
test/behavior/optional_stage1.zig created+284
......@@ -0,0 +1,284 @@
1const std = @import("std");
2const testing = std.testing;
3const expect = testing.expect;
4const expectEqual = testing.expectEqual;
5
6pub const EmptyStruct = struct {};
7
8test "optional pointer to size zero struct" {
9 var e = EmptyStruct{};
10 var o: ?*EmptyStruct = &e;
11 try expect(o != null);
12}
13
14test "equality compare nullable pointers" {
15 try testNullPtrsEql();
16 comptime try testNullPtrsEql();
17}
18
19fn testNullPtrsEql() !void {
20 var number: i32 = 1234;
21
22 var x: ?*i32 = null;
23 var y: ?*i32 = null;
24 try expect(x == y);
25 y = &number;
26 try expect(x != y);
27 try expect(x != &number);
28 try expect(&number != x);
29 x = &number;
30 try expect(x == y);
31 try expect(x == &number);
32 try expect(&number == x);
33}
34
35test "address of unwrap optional" {
36 const S = struct {
37 const Foo = struct {
38 a: i32,
39 };
40
41 var global: ?Foo = null;
42
43 pub fn getFoo() anyerror!*Foo {
44 return &global.?;
45 }
46 };
47 S.global = S.Foo{ .a = 1234 };
48 const foo = S.getFoo() catch unreachable;
49 try expect(foo.a == 1234);
50}
51
52test "equality compare optional with non-optional" {
53 try test_cmp_optional_non_optional();
54 comptime try test_cmp_optional_non_optional();
55}
56
57fn test_cmp_optional_non_optional() !void {
58 var ten: i32 = 10;
59 var opt_ten: ?i32 = 10;
60 var five: i32 = 5;
61 var int_n: ?i32 = null;
62
63 try expect(int_n != ten);
64 try expect(opt_ten == ten);
65 try expect(opt_ten != five);
66
67 // test evaluation is always lexical
68 // ensure that the optional isn't always computed before the non-optional
69 var mutable_state: i32 = 0;
70 _ = blk1: {
71 mutable_state += 1;
72 break :blk1 @as(?f64, 10.0);
73 } != blk2: {
74 try expect(mutable_state == 1);
75 break :blk2 @as(f64, 5.0);
76 };
77 _ = blk1: {
78 mutable_state += 1;
79 break :blk1 @as(f64, 10.0);
80 } != blk2: {
81 try expect(mutable_state == 2);
82 break :blk2 @as(?f64, 5.0);
83 };
84}
85
86test "passing an optional integer as a parameter" {
87 const S = struct {
88 fn entry() bool {
89 var x: i32 = 1234;
90 return foo(x);
91 }
92
93 fn foo(x: ?i32) bool {
94 return x.? == 1234;
95 }
96 };
97 try expect(S.entry());
98 comptime try expect(S.entry());
99}
100
101test "unwrap function call with optional pointer return value" {
102 const S = struct {
103 fn entry() !void {
104 try expect(foo().?.* == 1234);
105 try expect(bar() == null);
106 }
107 const global: i32 = 1234;
108 fn foo() ?*const i32 {
109 return &global;
110 }
111 fn bar() ?*i32 {
112 return null;
113 }
114 };
115 try S.entry();
116 comptime try S.entry();
117}
118
119test "nested orelse" {
120 const S = struct {
121 fn entry() !void {
122 try expect(func() == null);
123 }
124 fn maybe() ?Foo {
125 return null;
126 }
127 fn func() ?Foo {
128 const x = maybe() orelse
129 maybe() orelse
130 return null;
131 _ = x;
132 unreachable;
133 }
134 const Foo = struct {
135 field: i32,
136 };
137 };
138 try S.entry();
139 comptime try S.entry();
140}
141
142test "self-referential struct through a slice of optional" {
143 const S = struct {
144 const Node = struct {
145 children: []?Node,
146 data: ?u8,
147
148 fn new() Node {
149 return Node{
150 .children = undefined,
151 .data = null,
152 };
153 }
154 };
155 };
156
157 var n = S.Node.new();
158 try expect(n.data == null);
159}
160
161test "assigning to an unwrapped optional field in an inline loop" {
162 comptime var maybe_pos_arg: ?comptime_int = null;
163 inline for ("ab") |x| {
164 _ = x;
165 maybe_pos_arg = 0;
166 if (maybe_pos_arg.? != 0) {
167 @compileError("bad");
168 }
169 maybe_pos_arg.? = 10;
170 }
171}
172
173test "coerce an anon struct literal to optional struct" {
174 const S = struct {
175 const Struct = struct {
176 field: u32,
177 };
178 fn doTheTest() !void {
179 var maybe_dims: ?Struct = null;
180 maybe_dims = .{ .field = 1 };
181 try expect(maybe_dims.?.field == 1);
182 }
183 };
184 try S.doTheTest();
185 comptime try S.doTheTest();
186}
187
188test "optional with void type" {
189 const Foo = struct {
190 x: ?void,
191 };
192 var x = Foo{ .x = null };
193 try expect(x.x == null);
194}
195
196test "0-bit child type coerced to optional return ptr result location" {
197 const S = struct {
198 fn doTheTest() !void {
199 var y = Foo{};
200 var z = y.thing();
201 try expect(z != null);
202 }
203
204 const Foo = struct {
205 pub const Bar = struct {
206 field: *Foo,
207 };
208
209 pub fn thing(self: *Foo) ?Bar {
210 return Bar{ .field = self };
211 }
212 };
213 };
214 try S.doTheTest();
215 comptime try S.doTheTest();
216}
217
218test "0-bit child type coerced to optional" {
219 const S = struct {
220 fn doTheTest() !void {
221 var it: Foo = .{
222 .list = undefined,
223 };
224 try expect(it.foo() != null);
225 }
226
227 const Empty = struct {};
228 const Foo = struct {
229 list: [10]Empty,
230
231 fn foo(self: *Foo) ?*Empty {
232 const data = &self.list[0];
233 return data;
234 }
235 };
236 };
237 try S.doTheTest();
238 comptime try S.doTheTest();
239}
240
241test "array of optional unaligned types" {
242 const Enum = enum { one, two, three };
243
244 const SomeUnion = union(enum) {
245 Num: Enum,
246 Other: u32,
247 };
248
249 const values = [_]?SomeUnion{
250 SomeUnion{ .Num = .one },
251 SomeUnion{ .Num = .two },
252 SomeUnion{ .Num = .three },
253 SomeUnion{ .Num = .one },
254 SomeUnion{ .Num = .two },
255 SomeUnion{ .Num = .three },
256 };
257
258 // The index must be a runtime value
259 var i: usize = 0;
260 try expectEqual(Enum.one, values[i].?.Num);
261 i += 1;
262 try expectEqual(Enum.two, values[i].?.Num);
263 i += 1;
264 try expectEqual(Enum.three, values[i].?.Num);
265 i += 1;
266 try expectEqual(Enum.one, values[i].?.Num);
267 i += 1;
268 try expectEqual(Enum.two, values[i].?.Num);
269 i += 1;
270 try expectEqual(Enum.three, values[i].?.Num);
271}
272
273test "nested optional field in struct" {
274 const S2 = struct {
275 y: u8,
276 };
277 const S1 = struct {
278 x: ?S2,
279 };
280 var s = S1{
281 .x = S2{ .y = 127 },
282 };
283 try expect(s.x.?.y == 127);
284}
test/behavior/slice_stage1.zig+41
......@@ -20,6 +20,47 @@ test "slicing" {
2020 if (slice_rest.len != 10) unreachable;
2121}
2222
23test "slicing zero length array" {
24 const s1 = ""[0..];
25 const s2 = ([_]u32{})[0..];
26 try expect(s1.len == 0);
27 try expect(s2.len == 0);
28 try expect(mem.eql(u8, s1, ""));
29 try expect(mem.eql(u32, s2, &[_]u32{}));
30}
31
32test "slice string literal has correct type" {
33 comptime {
34 try expect(@TypeOf("aoeu"[0..]) == *const [4:0]u8);
35 const array = [_]i32{ 1, 2, 3, 4 };
36 try expect(@TypeOf(array[0..]) == *const [4]i32);
37 }
38 var runtime_zero: usize = 0;
39 comptime try expect(@TypeOf("aoeu"[runtime_zero..]) == [:0]const u8);
40 const array = [_]i32{ 1, 2, 3, 4 };
41 comptime try expect(@TypeOf(array[runtime_zero..]) == []const i32);
42}
43
44test "generic malloc free" {
45 const a = memAlloc(u8, 10) catch unreachable;
46 memFree(u8, a);
47}
48var some_mem: [100]u8 = undefined;
49fn memAlloc(comptime T: type, n: usize) anyerror![]T {
50 return @ptrCast([*]T, &some_mem[0])[0..n];
51}
52fn memFree(comptime T: type, memory: []T) void {
53 _ = memory;
54}
55
56test "result location zero sized array inside struct field implicit cast to slice" {
57 const E = struct {
58 entries: []u32,
59 };
60 var foo = E{ .entries = &[_]u32{} };
61 try expect(foo.entries.len == 0);
62}
63
2364const x = @intToPtr([*]i32, 0x1000)[0..0x500];
2465const y = x[0x100..];
2566test "compile time slice of pointer to hard coded address" {