authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-26 20:59:20-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-26 20:59:20-07:00
log35423b005440c9f31a4cc6a53ccf6b7edd08b859
tree8dffff28ae0950fb03d8d146f25985a813f492d0
parent82bd0ac572f14d1e3a13737f4daf00a1ee8041a2

organize behavior tests

check the set of passing tests; move towards the disabling logic being inside each test rather than which files are included. this enables a few more passing tests.

13 files changed, 1034 insertions(+), 972 deletions(-)

test/behavior.zig+1-8
...@@ -1,7 +1,6 @@...@@ -1,7 +1,6 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
22
3test {3test {
4 // Tests that pass for stage1, llvm backend, C backend, wasm backend, arm backend and x86_64 backend.
5 _ = @import("behavior/align.zig");4 _ = @import("behavior/align.zig");
6 _ = @import("behavior/alignof.zig");5 _ = @import("behavior/alignof.zig");
7 _ = @import("behavior/array.zig");6 _ = @import("behavior/array.zig");
...@@ -26,7 +25,6 @@ test {...@@ -26,7 +25,6 @@ test {
26 _ = @import("behavior/cast.zig");25 _ = @import("behavior/cast.zig");
27 _ = @import("behavior/comptime_memory.zig");26 _ = @import("behavior/comptime_memory.zig");
28 _ = @import("behavior/fn_in_struct_in_comptime.zig");27 _ = @import("behavior/fn_in_struct_in_comptime.zig");
29 _ = @import("behavior/generics_llvm.zig");
30 _ = @import("behavior/hasdecl.zig");28 _ = @import("behavior/hasdecl.zig");
31 _ = @import("behavior/hasfield.zig");29 _ = @import("behavior/hasfield.zig");
32 _ = @import("behavior/namespace_depends_on_compile_var.zig");30 _ = @import("behavior/namespace_depends_on_compile_var.zig");
...@@ -43,6 +41,7 @@ test {...@@ -43,6 +41,7 @@ test {
43 _ = @import("behavior/bitcast.zig");41 _ = @import("behavior/bitcast.zig");
44 _ = @import("behavior/bugs/624.zig");42 _ = @import("behavior/bugs/624.zig");
45 _ = @import("behavior/bugs/704.zig");43 _ = @import("behavior/bugs/704.zig");
44 _ = @import("behavior/bugs/1076.zig");
46 _ = @import("behavior/bugs/1486.zig");45 _ = @import("behavior/bugs/1486.zig");
47 _ = @import("behavior/bugs/2692.zig");46 _ = @import("behavior/bugs/2692.zig");
48 _ = @import("behavior/bugs/2889.zig");47 _ = @import("behavior/bugs/2889.zig");
...@@ -128,7 +127,6 @@ test {...@@ -128,7 +127,6 @@ test {
128 _ = @import("behavior/bugs/726.zig");127 _ = @import("behavior/bugs/726.zig");
129 _ = @import("behavior/bugs/828.zig");128 _ = @import("behavior/bugs/828.zig");
130 _ = @import("behavior/bugs/920.zig");129 _ = @import("behavior/bugs/920.zig");
131 _ = @import("behavior/bugs/1076.zig");
132 _ = @import("behavior/bugs/1120.zig");130 _ = @import("behavior/bugs/1120.zig");
133 _ = @import("behavior/bugs/1421.zig");131 _ = @import("behavior/bugs/1421.zig");
134 _ = @import("behavior/bugs/1442.zig");132 _ = @import("behavior/bugs/1442.zig");
...@@ -150,9 +148,7 @@ test {...@@ -150,9 +148,7 @@ test {
150 _ = @import("behavior/bugs/7047.zig");148 _ = @import("behavior/bugs/7047.zig");
151 _ = @import("behavior/bugs/10147.zig");149 _ = @import("behavior/bugs/10147.zig");
152 _ = @import("behavior/byteswap.zig");150 _ = @import("behavior/byteswap.zig");
153 _ = @import("behavior/call_stage1.zig");
154 _ = @import("behavior/const_slice_child.zig");151 _ = @import("behavior/const_slice_child.zig");
155 _ = @import("behavior/error_stage1.zig");
156 _ = @import("behavior/field_parent_ptr.zig");152 _ = @import("behavior/field_parent_ptr.zig");
157 _ = @import("behavior/floatop_stage1.zig");153 _ = @import("behavior/floatop_stage1.zig");
158 _ = @import("behavior/fn_delegation.zig");154 _ = @import("behavior/fn_delegation.zig");
...@@ -164,14 +160,12 @@ test {...@@ -164,14 +160,12 @@ test {
164 _ = @import("behavior/optional_stage1.zig");160 _ = @import("behavior/optional_stage1.zig");
165 _ = @import("behavior/popcount_stage1.zig");161 _ = @import("behavior/popcount_stage1.zig");
166 _ = @import("behavior/reflection.zig");162 _ = @import("behavior/reflection.zig");
167 _ = @import("behavior/saturating_arithmetic_stage1.zig");
168 _ = @import("behavior/select.zig");163 _ = @import("behavior/select.zig");
169 _ = @import("behavior/shuffle.zig");164 _ = @import("behavior/shuffle.zig");
170 _ = @import("behavior/sizeof_and_typeof_stage1.zig");165 _ = @import("behavior/sizeof_and_typeof_stage1.zig");
171 _ = @import("behavior/slice_stage1.zig");166 _ = @import("behavior/slice_stage1.zig");
172 _ = @import("behavior/struct_contains_null_ptr_itself.zig");167 _ = @import("behavior/struct_contains_null_ptr_itself.zig");
173 _ = @import("behavior/struct_contains_slice_of_itself.zig");168 _ = @import("behavior/struct_contains_slice_of_itself.zig");
174 _ = @import("behavior/struct_stage1.zig");
175 _ = @import("behavior/switch_prong_err_enum.zig");169 _ = @import("behavior/switch_prong_err_enum.zig");
176 _ = @import("behavior/switch_prong_implicit_cast.zig");170 _ = @import("behavior/switch_prong_implicit_cast.zig");
177 _ = @import("behavior/truncate_stage1.zig");171 _ = @import("behavior/truncate_stage1.zig");
...@@ -185,7 +179,6 @@ test {...@@ -185,7 +179,6 @@ test {
185 if (builtin.target.cpu.arch == .wasm32) {179 if (builtin.target.cpu.arch == .wasm32) {
186 _ = @import("behavior/wasm.zig");180 _ = @import("behavior/wasm.zig");
187 }181 }
188 _ = @import("behavior/translate_c_macros_stage1.zig");
189 }182 }
190 }183 }
191 }184 }
test/behavior/call.zig+78
...@@ -1,3 +1,81 @@...@@ -1,3 +1,81 @@
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;
5
6test "basic invocations" {
7 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
8
9 const foo = struct {
10 fn foo() i32 {
11 return 1234;
12 }
13 }.foo;
14 try expect(@call(.{}, foo, .{}) == 1234);
15 comptime {
16 // modifiers that allow comptime calls
17 try expect(@call(.{}, foo, .{}) == 1234);
18 try expect(@call(.{ .modifier = .no_async }, foo, .{}) == 1234);
19 try expect(@call(.{ .modifier = .always_tail }, foo, .{}) == 1234);
20 try expect(@call(.{ .modifier = .always_inline }, foo, .{}) == 1234);
21 }
22 {
23 // comptime call without comptime keyword
24 const result = @call(.{ .modifier = .compile_time }, foo, .{}) == 1234;
25 comptime try expect(result);
26 }
27 {
28 // call of non comptime-known function
29 var alias_foo = foo;
30 try expect(@call(.{ .modifier = .no_async }, alias_foo, .{}) == 1234);
31 try expect(@call(.{ .modifier = .never_tail }, alias_foo, .{}) == 1234);
32 try expect(@call(.{ .modifier = .never_inline }, alias_foo, .{}) == 1234);
33 }
34}
35
36test "tuple parameters" {
37 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
38
39 const add = struct {
40 fn add(a: i32, b: i32) i32 {
41 return a + b;
42 }
43 }.add;
44 var a: i32 = 12;
45 var b: i32 = 34;
46 try expect(@call(.{}, add, .{ a, 34 }) == 46);
47 try expect(@call(.{}, add, .{ 12, b }) == 46);
48 try expect(@call(.{}, add, .{ a, b }) == 46);
49 try expect(@call(.{}, add, .{ 12, 34 }) == 46);
50 comptime try expect(@call(.{}, add, .{ 12, 34 }) == 46);
51 {
52 const separate_args0 = .{ a, b };
53 const separate_args1 = .{ a, 34 };
54 const separate_args2 = .{ 12, 34 };
55 const separate_args3 = .{ 12, b };
56 try expect(@call(.{ .modifier = .always_inline }, add, separate_args0) == 46);
57 try expect(@call(.{ .modifier = .always_inline }, add, separate_args1) == 46);
58 try expect(@call(.{ .modifier = .always_inline }, add, separate_args2) == 46);
59 try expect(@call(.{ .modifier = .always_inline }, add, separate_args3) == 46);
60 }
61}
62
63test "comptime call with bound function as parameter" {
64 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
65
66 const S = struct {
67 fn ReturnType(func: anytype) type {
68 return switch (@typeInfo(@TypeOf(func))) {
69 .BoundFn => |info| info,
70 else => unreachable,
71 }.return_type orelse void;
72 }
73
74 fn call_me_maybe() ?i32 {
75 return 123;
76 }
77 };
78
79 var inst: S = undefined;
80 try expectEqual(?i32, S.ReturnType(inst.call_me_maybe));
81}
test/behavior/call_stage1.zig deleted-74
...@@ -1,74 +0,0 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;
4
5test "basic invocations" {
6 const foo = struct {
7 fn foo() i32 {
8 return 1234;
9 }
10 }.foo;
11 try expect(@call(.{}, foo, .{}) == 1234);
12 comptime {
13 // modifiers that allow comptime calls
14 try expect(@call(.{}, foo, .{}) == 1234);
15 try expect(@call(.{ .modifier = .no_async }, foo, .{}) == 1234);
16 try expect(@call(.{ .modifier = .always_tail }, foo, .{}) == 1234);
17 try expect(@call(.{ .modifier = .always_inline }, foo, .{}) == 1234);
18 }
19 {
20 // comptime call without comptime keyword
21 const result = @call(.{ .modifier = .compile_time }, foo, .{}) == 1234;
22 comptime try expect(result);
23 }
24 {
25 // call of non comptime-known function
26 var alias_foo = foo;
27 try expect(@call(.{ .modifier = .no_async }, alias_foo, .{}) == 1234);
28 try expect(@call(.{ .modifier = .never_tail }, alias_foo, .{}) == 1234);
29 try expect(@call(.{ .modifier = .never_inline }, alias_foo, .{}) == 1234);
30 }
31}
32
33test "tuple parameters" {
34 const add = struct {
35 fn add(a: i32, b: i32) i32 {
36 return a + b;
37 }
38 }.add;
39 var a: i32 = 12;
40 var b: i32 = 34;
41 try expect(@call(.{}, add, .{ a, 34 }) == 46);
42 try expect(@call(.{}, add, .{ 12, b }) == 46);
43 try expect(@call(.{}, add, .{ a, b }) == 46);
44 try expect(@call(.{}, add, .{ 12, 34 }) == 46);
45 comptime try expect(@call(.{}, add, .{ 12, 34 }) == 46);
46 {
47 const separate_args0 = .{ a, b };
48 const separate_args1 = .{ a, 34 };
49 const separate_args2 = .{ 12, 34 };
50 const separate_args3 = .{ 12, b };
51 try expect(@call(.{ .modifier = .always_inline }, add, separate_args0) == 46);
52 try expect(@call(.{ .modifier = .always_inline }, add, separate_args1) == 46);
53 try expect(@call(.{ .modifier = .always_inline }, add, separate_args2) == 46);
54 try expect(@call(.{ .modifier = .always_inline }, add, separate_args3) == 46);
55 }
56}
57
58test "comptime call with bound function as parameter" {
59 const S = struct {
60 fn ReturnType(func: anytype) type {
61 return switch (@typeInfo(@TypeOf(func))) {
62 .BoundFn => |info| info,
63 else => unreachable,
64 }.return_type orelse void;
65 }
66
67 fn call_me_maybe() ?i32 {
68 return 123;
69 }
70 };
71
72 var inst: S = undefined;
73 try expectEqual(?i32, S.ReturnType(inst.call_me_maybe));
74}
test/behavior/error.zig+346
...@@ -132,3 +132,349 @@ fn foo2(f: fn () anyerror!void) void {...@@ -132,3 +132,349 @@ fn foo2(f: fn () anyerror!void) void {
132}132}
133133
134fn bar2() (error{}!void) {}134fn bar2() (error{}!void) {}
135
136test "error union type " {
137 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
138
139 try testErrorUnionType();
140 comptime try testErrorUnionType();
141}
142
143fn testErrorUnionType() !void {
144 const x: anyerror!i32 = 1234;
145 if (x) |value| try expect(value == 1234) else |_| unreachable;
146 try expect(@typeInfo(@TypeOf(x)) == .ErrorUnion);
147 try expect(@typeInfo(@typeInfo(@TypeOf(x)).ErrorUnion.error_set) == .ErrorSet);
148 try expect(@typeInfo(@TypeOf(x)).ErrorUnion.error_set == anyerror);
149}
150
151test "error set type" {
152 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
153
154 try testErrorSetType();
155 comptime try testErrorSetType();
156}
157
158const MyErrSet = error{
159 OutOfMemory,
160 FileNotFound,
161};
162
163fn testErrorSetType() !void {
164 try expect(@typeInfo(MyErrSet).ErrorSet.?.len == 2);
165
166 const a: MyErrSet!i32 = 5678;
167 const b: MyErrSet!i32 = MyErrSet.OutOfMemory;
168 try expect(b catch error.OutOfMemory == error.OutOfMemory);
169
170 if (a) |value| try expect(value == 5678) else |err| switch (err) {
171 error.OutOfMemory => unreachable,
172 error.FileNotFound => unreachable,
173 }
174}
175
176test "explicit error set cast" {
177 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
178
179 try testExplicitErrorSetCast(Set1.A);
180 comptime try testExplicitErrorSetCast(Set1.A);
181}
182
183const Set1 = error{ A, B };
184const Set2 = error{ A, C };
185
186fn testExplicitErrorSetCast(set1: Set1) !void {
187 var x = @errSetCast(Set2, set1);
188 var y = @errSetCast(Set1, x);
189 try expect(y == error.A);
190}
191
192test "comptime test error for empty error set" {
193 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
194
195 try testComptimeTestErrorEmptySet(1234);
196 comptime try testComptimeTestErrorEmptySet(1234);
197}
198
199const EmptyErrorSet = error{};
200
201fn testComptimeTestErrorEmptySet(x: EmptyErrorSet!i32) !void {
202 if (x) |v| try expect(v == 1234) else |err| {
203 _ = err;
204 @compileError("bad");
205 }
206}
207
208test "comptime err to int of error set with only 1 possible value" {
209 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
210
211 testErrToIntWithOnePossibleValue(error.A, @errorToInt(error.A));
212 comptime testErrToIntWithOnePossibleValue(error.A, @errorToInt(error.A));
213}
214fn testErrToIntWithOnePossibleValue(
215 x: error{A},
216 comptime value: u32,
217) void {
218 if (@errorToInt(x) != value) {
219 @compileError("bad");
220 }
221}
222
223test "error union peer type resolution" {
224 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
225
226 try testErrorUnionPeerTypeResolution(1);
227}
228
229fn testErrorUnionPeerTypeResolution(x: i32) !void {
230 const y = switch (x) {
231 1 => bar_1(),
232 2 => baz_1(),
233 else => quux_1(),
234 };
235 if (y) |_| {
236 @panic("expected error");
237 } else |e| {
238 try expect(e == error.A);
239 }
240}
241
242fn bar_1() anyerror {
243 return error.A;
244}
245
246fn baz_1() !i32 {
247 return error.B;
248}
249
250fn quux_1() !i32 {
251 return error.C;
252}
253
254test "error: Zero sized error set returned with value payload crash" {
255 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
256
257 _ = foo3(0) catch {};
258 _ = comptime foo3(0) catch {};
259}
260
261const Error = error{};
262fn foo3(b: usize) Error!usize {
263 return b;
264}
265
266test "error: Infer error set from literals" {
267 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
268
269 _ = nullLiteral("n") catch |err| handleErrors(err);
270 _ = floatLiteral("n") catch |err| handleErrors(err);
271 _ = intLiteral("n") catch |err| handleErrors(err);
272 _ = comptime nullLiteral("n") catch |err| handleErrors(err);
273 _ = comptime floatLiteral("n") catch |err| handleErrors(err);
274 _ = comptime intLiteral("n") catch |err| handleErrors(err);
275}
276
277fn handleErrors(err: anytype) noreturn {
278 switch (err) {
279 error.T => {},
280 }
281
282 unreachable;
283}
284
285fn nullLiteral(str: []const u8) !?i64 {
286 if (str[0] == 'n') return null;
287
288 return error.T;
289}
290
291fn floatLiteral(str: []const u8) !?f64 {
292 if (str[0] == 'n') return 1.0;
293
294 return error.T;
295}
296
297fn intLiteral(str: []const u8) !?i64 {
298 if (str[0] == 'n') return 1;
299
300 return error.T;
301}
302
303test "nested error union function call in optional unwrap" {
304 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
305
306 const S = struct {
307 const Foo = struct {
308 a: i32,
309 };
310
311 fn errorable() !i32 {
312 var x: Foo = (try getFoo()) orelse return error.Other;
313 return x.a;
314 }
315
316 fn errorable2() !i32 {
317 var x: Foo = (try getFoo2()) orelse return error.Other;
318 return x.a;
319 }
320
321 fn errorable3() !i32 {
322 var x: Foo = (try getFoo3()) orelse return error.Other;
323 return x.a;
324 }
325
326 fn getFoo() anyerror!?Foo {
327 return Foo{ .a = 1234 };
328 }
329
330 fn getFoo2() anyerror!?Foo {
331 return error.Failure;
332 }
333
334 fn getFoo3() anyerror!?Foo {
335 return null;
336 }
337 };
338 try expect((try S.errorable()) == 1234);
339 try expectError(error.Failure, S.errorable2());
340 try expectError(error.Other, S.errorable3());
341 comptime {
342 try expect((try S.errorable()) == 1234);
343 try expectError(error.Failure, S.errorable2());
344 try expectError(error.Other, S.errorable3());
345 }
346}
347
348test "return function call to error set from error union function" {
349 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
350
351 const S = struct {
352 fn errorable() anyerror!i32 {
353 return fail();
354 }
355
356 fn fail() anyerror {
357 return error.Failure;
358 }
359 };
360 try expectError(error.Failure, S.errorable());
361 comptime try expectError(error.Failure, S.errorable());
362}
363
364test "optional error set is the same size as error set" {
365 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
366
367 comptime try expect(@sizeOf(?anyerror) == @sizeOf(anyerror));
368 const S = struct {
369 fn returnsOptErrSet() ?anyerror {
370 return null;
371 }
372 };
373 try expect(S.returnsOptErrSet() == null);
374 comptime try expect(S.returnsOptErrSet() == null);
375}
376
377test "nested catch" {
378 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
379
380 const S = struct {
381 fn entry() !void {
382 try expectError(error.Bad, func());
383 }
384 fn fail() anyerror!Foo {
385 return error.Wrong;
386 }
387 fn func() anyerror!Foo {
388 _ = fail() catch
389 fail() catch
390 return error.Bad;
391 unreachable;
392 }
393 const Foo = struct {
394 field: i32,
395 };
396 };
397 try S.entry();
398 comptime try S.entry();
399}
400
401test "function pointer with return type that is error union with payload which is pointer of parent struct" {
402 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
403
404 const S = struct {
405 const Foo = struct {
406 fun: fn (a: i32) (anyerror!*Foo),
407 };
408
409 const Err = error{UnspecifiedErr};
410
411 fn bar(a: i32) anyerror!*Foo {
412 _ = a;
413 return Err.UnspecifiedErr;
414 }
415
416 fn doTheTest() !void {
417 var x = Foo{ .fun = @This().bar };
418 try expectError(error.UnspecifiedErr, x.fun(1));
419 }
420 };
421 try S.doTheTest();
422}
423
424test "return result loc as peer result loc in inferred error set function" {
425 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
426
427 const S = struct {
428 fn doTheTest() !void {
429 if (quux(2)) |x| {
430 try expect(x.Two);
431 } else |e| switch (e) {
432 error.Whatever => @panic("fail"),
433 }
434 try expectError(error.Whatever, quux(99));
435 }
436 const FormValue = union(enum) {
437 One: void,
438 Two: bool,
439 };
440
441 fn quux(id: u64) !FormValue {
442 return switch (id) {
443 2 => FormValue{ .Two = true },
444 1 => FormValue{ .One = {} },
445 else => return error.Whatever,
446 };
447 }
448 };
449 try S.doTheTest();
450 comptime try S.doTheTest();
451}
452
453test "error payload type is correctly resolved" {
454 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
455
456 const MyIntWrapper = struct {
457 const Self = @This();
458
459 x: i32,
460
461 pub fn create() anyerror!Self {
462 return Self{ .x = 42 };
463 }
464 };
465
466 try expectEqual(MyIntWrapper{ .x = 42 }, try MyIntWrapper.create());
467}
468
469test "error union comptime caching" {
470 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
471
472 const S = struct {
473 fn quux(comptime arg: anytype) void {
474 arg catch {};
475 }
476 };
477
478 S.quux(@as(anyerror!void, {}));
479 S.quux(@as(anyerror!void, {}));
480}
test/behavior/error_stage1.zig deleted-319
...@@ -1,319 +0,0 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const expectError = std.testing.expectError;
4const expectEqual = std.testing.expectEqual;
5const mem = std.mem;
6
7test "error union type " {
8 try testErrorUnionType();
9 comptime try testErrorUnionType();
10}
11
12fn testErrorUnionType() !void {
13 const x: anyerror!i32 = 1234;
14 if (x) |value| try expect(value == 1234) else |_| unreachable;
15 try expect(@typeInfo(@TypeOf(x)) == .ErrorUnion);
16 try expect(@typeInfo(@typeInfo(@TypeOf(x)).ErrorUnion.error_set) == .ErrorSet);
17 try expect(@typeInfo(@TypeOf(x)).ErrorUnion.error_set == anyerror);
18}
19
20test "error set type" {
21 try testErrorSetType();
22 comptime try testErrorSetType();
23}
24
25const MyErrSet = error{
26 OutOfMemory,
27 FileNotFound,
28};
29
30fn testErrorSetType() !void {
31 try expect(@typeInfo(MyErrSet).ErrorSet.?.len == 2);
32
33 const a: MyErrSet!i32 = 5678;
34 const b: MyErrSet!i32 = MyErrSet.OutOfMemory;
35 try expect(b catch error.OutOfMemory == error.OutOfMemory);
36
37 if (a) |value| try expect(value == 5678) else |err| switch (err) {
38 error.OutOfMemory => unreachable,
39 error.FileNotFound => unreachable,
40 }
41}
42
43test "explicit error set cast" {
44 try testExplicitErrorSetCast(Set1.A);
45 comptime try testExplicitErrorSetCast(Set1.A);
46}
47
48const Set1 = error{ A, B };
49const Set2 = error{ A, C };
50
51fn testExplicitErrorSetCast(set1: Set1) !void {
52 var x = @errSetCast(Set2, set1);
53 var y = @errSetCast(Set1, x);
54 try expect(y == error.A);
55}
56
57test "comptime test error for empty error set" {
58 try testComptimeTestErrorEmptySet(1234);
59 comptime try testComptimeTestErrorEmptySet(1234);
60}
61
62const EmptyErrorSet = error{};
63
64fn testComptimeTestErrorEmptySet(x: EmptyErrorSet!i32) !void {
65 if (x) |v| try expect(v == 1234) else |err| {
66 _ = err;
67 @compileError("bad");
68 }
69}
70
71test "comptime err to int of error set with only 1 possible value" {
72 testErrToIntWithOnePossibleValue(error.A, @errorToInt(error.A));
73 comptime testErrToIntWithOnePossibleValue(error.A, @errorToInt(error.A));
74}
75fn testErrToIntWithOnePossibleValue(
76 x: error{A},
77 comptime value: u32,
78) void {
79 if (@errorToInt(x) != value) {
80 @compileError("bad");
81 }
82}
83
84test "error union peer type resolution" {
85 try testErrorUnionPeerTypeResolution(1);
86}
87
88fn testErrorUnionPeerTypeResolution(x: i32) !void {
89 const y = switch (x) {
90 1 => bar_1(),
91 2 => baz_1(),
92 else => quux_1(),
93 };
94 if (y) |_| {
95 @panic("expected error");
96 } else |e| {
97 try expect(e == error.A);
98 }
99}
100
101fn bar_1() anyerror {
102 return error.A;
103}
104
105fn baz_1() !i32 {
106 return error.B;
107}
108
109fn quux_1() !i32 {
110 return error.C;
111}
112
113test "error: Zero sized error set returned with value payload crash" {
114 _ = foo3(0) catch {};
115 _ = comptime foo3(0) catch {};
116}
117
118const Error = error{};
119fn foo3(b: usize) Error!usize {
120 return b;
121}
122
123test "error: Infer error set from literals" {
124 _ = nullLiteral("n") catch |err| handleErrors(err);
125 _ = floatLiteral("n") catch |err| handleErrors(err);
126 _ = intLiteral("n") catch |err| handleErrors(err);
127 _ = comptime nullLiteral("n") catch |err| handleErrors(err);
128 _ = comptime floatLiteral("n") catch |err| handleErrors(err);
129 _ = comptime intLiteral("n") catch |err| handleErrors(err);
130}
131
132fn handleErrors(err: anytype) noreturn {
133 switch (err) {
134 error.T => {},
135 }
136
137 unreachable;
138}
139
140fn nullLiteral(str: []const u8) !?i64 {
141 if (str[0] == 'n') return null;
142
143 return error.T;
144}
145
146fn floatLiteral(str: []const u8) !?f64 {
147 if (str[0] == 'n') return 1.0;
148
149 return error.T;
150}
151
152fn intLiteral(str: []const u8) !?i64 {
153 if (str[0] == 'n') return 1;
154
155 return error.T;
156}
157
158test "nested error union function call in optional unwrap" {
159 const S = struct {
160 const Foo = struct {
161 a: i32,
162 };
163
164 fn errorable() !i32 {
165 var x: Foo = (try getFoo()) orelse return error.Other;
166 return x.a;
167 }
168
169 fn errorable2() !i32 {
170 var x: Foo = (try getFoo2()) orelse return error.Other;
171 return x.a;
172 }
173
174 fn errorable3() !i32 {
175 var x: Foo = (try getFoo3()) orelse return error.Other;
176 return x.a;
177 }
178
179 fn getFoo() anyerror!?Foo {
180 return Foo{ .a = 1234 };
181 }
182
183 fn getFoo2() anyerror!?Foo {
184 return error.Failure;
185 }
186
187 fn getFoo3() anyerror!?Foo {
188 return null;
189 }
190 };
191 try expect((try S.errorable()) == 1234);
192 try expectError(error.Failure, S.errorable2());
193 try expectError(error.Other, S.errorable3());
194 comptime {
195 try expect((try S.errorable()) == 1234);
196 try expectError(error.Failure, S.errorable2());
197 try expectError(error.Other, S.errorable3());
198 }
199}
200
201test "return function call to error set from error union function" {
202 const S = struct {
203 fn errorable() anyerror!i32 {
204 return fail();
205 }
206
207 fn fail() anyerror {
208 return error.Failure;
209 }
210 };
211 try expectError(error.Failure, S.errorable());
212 comptime try expectError(error.Failure, S.errorable());
213}
214
215test "optional error set is the same size as error set" {
216 comptime try expect(@sizeOf(?anyerror) == @sizeOf(anyerror));
217 const S = struct {
218 fn returnsOptErrSet() ?anyerror {
219 return null;
220 }
221 };
222 try expect(S.returnsOptErrSet() == null);
223 comptime try expect(S.returnsOptErrSet() == null);
224}
225
226test "nested catch" {
227 const S = struct {
228 fn entry() !void {
229 try expectError(error.Bad, func());
230 }
231 fn fail() anyerror!Foo {
232 return error.Wrong;
233 }
234 fn func() anyerror!Foo {
235 _ = fail() catch
236 fail() catch
237 return error.Bad;
238 unreachable;
239 }
240 const Foo = struct {
241 field: i32,
242 };
243 };
244 try S.entry();
245 comptime try S.entry();
246}
247
248test "function pointer with return type that is error union with payload which is pointer of parent struct" {
249 const S = struct {
250 const Foo = struct {
251 fun: fn (a: i32) (anyerror!*Foo),
252 };
253
254 const Err = error{UnspecifiedErr};
255
256 fn bar(a: i32) anyerror!*Foo {
257 _ = a;
258 return Err.UnspecifiedErr;
259 }
260
261 fn doTheTest() !void {
262 var x = Foo{ .fun = @This().bar };
263 try expectError(error.UnspecifiedErr, x.fun(1));
264 }
265 };
266 try S.doTheTest();
267}
268
269test "return result loc as peer result loc in inferred error set function" {
270 const S = struct {
271 fn doTheTest() !void {
272 if (quux(2)) |x| {
273 try expect(x.Two);
274 } else |e| switch (e) {
275 error.Whatever => @panic("fail"),
276 }
277 try expectError(error.Whatever, quux(99));
278 }
279 const FormValue = union(enum) {
280 One: void,
281 Two: bool,
282 };
283
284 fn quux(id: u64) !FormValue {
285 return switch (id) {
286 2 => FormValue{ .Two = true },
287 1 => FormValue{ .One = {} },
288 else => return error.Whatever,
289 };
290 }
291 };
292 try S.doTheTest();
293 comptime try S.doTheTest();
294}
295
296test "error payload type is correctly resolved" {
297 const MyIntWrapper = struct {
298 const Self = @This();
299
300 x: i32,
301
302 pub fn create() anyerror!Self {
303 return Self{ .x = 42 };
304 }
305 };
306
307 try expectEqual(MyIntWrapper{ .x = 42 }, try MyIntWrapper.create());
308}
309
310test "error union comptime caching" {
311 const S = struct {
312 fn quux(comptime arg: anytype) void {
313 arg catch {};
314 }
315 };
316
317 S.quux(@as(anyerror!void, {}));
318 S.quux(@as(anyerror!void, {}));
319}
test/behavior/generics.zig+46
...@@ -163,3 +163,49 @@ test "generic fn keeps non-generic parameter types" {...@@ -163,3 +163,49 @@ test "generic fn keeps non-generic parameter types" {
163 var x: [16]u8 align(A) = undefined;163 var x: [16]u8 align(A) = undefined;
164 try S.f(u8, &x);164 try S.f(u8, &x);
165}165}
166
167test "array of generic fns" {
168 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
169 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
170 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
171 try expect(foos[0](true));
172 try expect(!foos[1](true));
173}
174
175const foos = [_]fn (anytype) bool{
176 foo1,
177 foo2,
178};
179
180fn foo1(arg: anytype) bool {
181 return arg;
182}
183fn foo2(arg: anytype) bool {
184 return !arg;
185}
186
187test "generic struct" {
188 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
189 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
190 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
191 var a1 = GenNode(i32){
192 .value = 13,
193 .next = null,
194 };
195 var b1 = GenNode(bool){
196 .value = true,
197 .next = null,
198 };
199 try expect(a1.value == 13);
200 try expect(a1.value == a1.getVal());
201 try expect(b1.getVal());
202}
203fn GenNode(comptime T: type) type {
204 return struct {
205 value: T,
206 next: ?*GenNode(T),
207 fn getVal(n: *const GenNode(T)) T {
208 return n.value;
209 }
210 };
211}
test/behavior/generics_llvm.zig deleted-49
...@@ -1,49 +0,0 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const builtin = @import("builtin");
4
5const foos = [_]fn (anytype) bool{
6 foo1,
7 foo2,
8};
9
10fn foo1(arg: anytype) bool {
11 return arg;
12}
13fn foo2(arg: anytype) bool {
14 return !arg;
15}
16
17test "array of generic fns" {
18 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
19 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
20 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
21 try expect(foos[0](true));
22 try expect(!foos[1](true));
23}
24
25test "generic struct" {
26 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
27 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
28 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
29 var a1 = GenNode(i32){
30 .value = 13,
31 .next = null,
32 };
33 var b1 = GenNode(bool){
34 .value = true,
35 .next = null,
36 };
37 try expect(a1.value == 13);
38 try expect(a1.value == a1.getVal());
39 try expect(b1.getVal());
40}
41fn GenNode(comptime T: type) type {
42 return struct {
43 value: T,
44 next: ?*GenNode(T),
45 fn getVal(n: *const GenNode(T)) T {
46 return n.value;
47 }
48 };
49}
test/behavior/saturating_arithmetic.zig+22
...@@ -118,3 +118,25 @@ test "saturating shift-left" {...@@ -118,3 +118,25 @@ test "saturating shift-left" {
118 try S.doTheTest();118 try S.doTheTest();
119 comptime try S.doTheTest();119 comptime try S.doTheTest();
120}120}
121
122test "saturating shl uses the LHS type" {
123 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
124
125 const lhs_const: u8 = 1;
126 var lhs_var: u8 = 1;
127
128 const rhs_const: usize = 8;
129 var rhs_var: usize = 8;
130
131 try expect((lhs_const <<| 8) == 255);
132 try expect((lhs_const <<| rhs_const) == 255);
133 try expect((lhs_const <<| rhs_var) == 255);
134
135 try expect((lhs_var <<| 8) == 255);
136 try expect((lhs_var <<| rhs_const) == 255);
137 try expect((lhs_var <<| rhs_var) == 255);
138
139 try expect((@as(u8, 1) <<| 8) == 255);
140 try expect((@as(u8, 1) <<| rhs_const) == 255);
141 try expect((@as(u8, 1) <<| rhs_var) == 255);
142}
test/behavior/saturating_arithmetic_stage1.zig deleted-22
...@@ -1,22 +0,0 @@
1const std = @import("std");
2const expect = std.testing.expect;
3
4test "saturating shl uses the LHS type" {
5 const lhs_const: u8 = 1;
6 var lhs_var: u8 = 1;
7
8 const rhs_const: usize = 8;
9 var rhs_var: usize = 8;
10
11 try expect((lhs_const <<| 8) == 255);
12 try expect((lhs_const <<| rhs_const) == 255);
13 try expect((lhs_const <<| rhs_var) == 255);
14
15 try expect((lhs_var <<| 8) == 255);
16 try expect((lhs_var <<| rhs_const) == 255);
17 try expect((lhs_var <<| rhs_var) == 255);
18
19 try expect((@as(u8, 1) <<| 8) == 255);
20 try expect((@as(u8, 1) <<| rhs_const) == 255);
21 try expect((@as(u8, 1) <<| rhs_var) == 255);
22}
test/behavior/struct_llvm.zig+510
...@@ -305,3 +305,513 @@ test "default struct initialization fields" {...@@ -305,3 +305,513 @@ test "default struct initialization fields" {
305 try expect(y.b == x.b);305 try expect(y.b == x.b);
306 try expect(1239 == x.a + x.b);306 try expect(1239 == x.a + x.b);
307}307}
308
309// TODO revisit this test when doing https://github.com/ziglang/zig/issues/1512
310test "packed array 24bits" {
311 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
312
313 comptime {
314 try expect(@sizeOf([9]Foo32Bits) == 9 * 4);
315 try expect(@sizeOf(FooArray24Bits) == 2 + 2 * 4 + 2);
316 }
317
318 var bytes = [_]u8{0} ** (@sizeOf(FooArray24Bits) + 1);
319 bytes[bytes.len - 1] = 0xaa;
320 const ptr = &std.mem.bytesAsSlice(FooArray24Bits, bytes[0 .. bytes.len - 1])[0];
321 try expect(ptr.a == 0);
322 try expect(ptr.b[0].field == 0);
323 try expect(ptr.b[1].field == 0);
324 try expect(ptr.c == 0);
325
326 ptr.a = maxInt(u16);
327 try expect(ptr.a == maxInt(u16));
328 try expect(ptr.b[0].field == 0);
329 try expect(ptr.b[1].field == 0);
330 try expect(ptr.c == 0);
331
332 ptr.b[0].field = maxInt(u24);
333 try expect(ptr.a == maxInt(u16));
334 try expect(ptr.b[0].field == maxInt(u24));
335 try expect(ptr.b[1].field == 0);
336 try expect(ptr.c == 0);
337
338 ptr.b[1].field = maxInt(u24);
339 try expect(ptr.a == maxInt(u16));
340 try expect(ptr.b[0].field == maxInt(u24));
341 try expect(ptr.b[1].field == maxInt(u24));
342 try expect(ptr.c == 0);
343
344 ptr.c = maxInt(u16);
345 try expect(ptr.a == maxInt(u16));
346 try expect(ptr.b[0].field == maxInt(u24));
347 try expect(ptr.b[1].field == maxInt(u24));
348 try expect(ptr.c == maxInt(u16));
349
350 try expect(bytes[bytes.len - 1] == 0xaa);
351}
352
353const Foo32Bits = packed struct {
354 field: u24,
355 pad: u8,
356};
357
358const FooArray24Bits = packed struct {
359 a: u16,
360 b: [2]Foo32Bits,
361 c: u16,
362};
363
364test "aligned array of packed struct" {
365 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
366
367 comptime {
368 try expect(@sizeOf(FooStructAligned) == 2);
369 try expect(@sizeOf(FooArrayOfAligned) == 2 * 2);
370 }
371
372 var bytes = [_]u8{0xbb} ** @sizeOf(FooArrayOfAligned);
373 const ptr = &std.mem.bytesAsSlice(FooArrayOfAligned, bytes[0..])[0];
374
375 try expect(ptr.a[0].a == 0xbb);
376 try expect(ptr.a[0].b == 0xbb);
377 try expect(ptr.a[1].a == 0xbb);
378 try expect(ptr.a[1].b == 0xbb);
379}
380
381const FooStructAligned = packed struct {
382 a: u8,
383 b: u8,
384};
385
386const FooArrayOfAligned = packed struct {
387 a: [2]FooStructAligned,
388};
389
390test "pointer to packed struct member in a stack variable" {
391 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
392
393 const S = packed struct {
394 a: u2,
395 b: u2,
396 };
397
398 var s = S{ .a = 2, .b = 0 };
399 var b_ptr = &s.b;
400 try expect(s.b == 0);
401 b_ptr.* = 2;
402 try expect(s.b == 2);
403}
404
405test "non-byte-aligned array inside packed struct" {
406 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
407
408 const Foo = packed struct {
409 a: bool,
410 b: [0x16]u8,
411 };
412 const S = struct {
413 fn bar(slice: []const u8) !void {
414 try expectEqualSlices(u8, slice, "abcdefghijklmnopqurstu");
415 }
416 fn doTheTest() !void {
417 var foo = Foo{
418 .a = true,
419 .b = "abcdefghijklmnopqurstu".*,
420 };
421 const value = foo.b;
422 try bar(&value);
423 }
424 };
425 try S.doTheTest();
426 comptime try S.doTheTest();
427}
428
429test "packed struct with u0 field access" {
430 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
431
432 const S = packed struct {
433 f0: u0,
434 };
435 var s = S{ .f0 = 0 };
436 comptime try expect(s.f0 == 0);
437}
438
439test "access to global struct fields" {
440 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
441
442 g_foo.bar.value = 42;
443 try expect(g_foo.bar.value == 42);
444}
445
446const S0 = struct {
447 bar: S1,
448
449 pub const S1 = struct {
450 value: u8,
451 };
452
453 fn init() @This() {
454 return S0{ .bar = S1{ .value = 123 } };
455 }
456};
457
458var g_foo: S0 = S0.init();
459
460test "packed struct with fp fields" {
461 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
462
463 const S = packed struct {
464 data: [3]f32,
465
466 pub fn frob(self: *@This()) void {
467 self.data[0] += self.data[1] + self.data[2];
468 self.data[1] += self.data[0] + self.data[2];
469 self.data[2] += self.data[0] + self.data[1];
470 }
471 };
472
473 var s: S = undefined;
474 s.data[0] = 1.0;
475 s.data[1] = 2.0;
476 s.data[2] = 3.0;
477 s.frob();
478 try expectEqual(@as(f32, 6.0), s.data[0]);
479 try expectEqual(@as(f32, 11.0), s.data[1]);
480 try expectEqual(@as(f32, 20.0), s.data[2]);
481}
482
483test "fn with C calling convention returns struct by value" {
484 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
485
486 const S = struct {
487 fn entry() !void {
488 var x = makeBar(10);
489 try expectEqual(@as(i32, 10), x.handle);
490 }
491
492 const ExternBar = extern struct {
493 handle: i32,
494 };
495
496 fn makeBar(t: i32) callconv(.C) ExternBar {
497 return ExternBar{
498 .handle = t,
499 };
500 }
501 };
502 try S.entry();
503 comptime try S.entry();
504}
505
506test "non-packed struct with u128 entry in union" {
507 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
508
509 const U = union(enum) {
510 Num: u128,
511 Void,
512 };
513
514 const S = struct {
515 f1: U,
516 f2: U,
517 };
518
519 var sx: S = undefined;
520 var s = &sx;
521 try std.testing.expect(@ptrToInt(&s.f2) - @ptrToInt(&s.f1) == @offsetOf(S, "f2"));
522 var v2 = U{ .Num = 123 };
523 s.f2 = v2;
524 try std.testing.expect(s.f2.Num == 123);
525}
526
527test "packed struct field passed to generic function" {
528 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
529
530 const S = struct {
531 const P = packed struct {
532 b: u5,
533 g: u5,
534 r: u5,
535 a: u1,
536 };
537
538 fn genericReadPackedField(ptr: anytype) u5 {
539 return ptr.*;
540 }
541 };
542
543 var p: S.P = undefined;
544 p.b = 29;
545 var loaded = S.genericReadPackedField(&p.b);
546 try expect(loaded == 29);
547}
548
549test "anonymous struct literal syntax" {
550 const S = struct {
551 const Point = struct {
552 x: i32,
553 y: i32,
554 };
555
556 fn doTheTest() !void {
557 var p: Point = .{
558 .x = 1,
559 .y = 2,
560 };
561 try expect(p.x == 1);
562 try expect(p.y == 2);
563 }
564 };
565 try S.doTheTest();
566 comptime try S.doTheTest();
567}
568
569test "fully anonymous struct" {
570 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
571
572 const S = struct {
573 fn doTheTest() !void {
574 try dump(.{
575 .int = @as(u32, 1234),
576 .float = @as(f64, 12.34),
577 .b = true,
578 .s = "hi",
579 });
580 }
581 fn dump(args: anytype) !void {
582 try expect(args.int == 1234);
583 try expect(args.float == 12.34);
584 try expect(args.b);
585 try expect(args.s[0] == 'h');
586 try expect(args.s[1] == 'i');
587 }
588 };
589 try S.doTheTest();
590 comptime try S.doTheTest();
591}
592
593test "fully anonymous list literal" {
594 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
595
596 const S = struct {
597 fn doTheTest() !void {
598 try dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" });
599 }
600 fn dump(args: anytype) !void {
601 try expect(args.@"0" == 1234);
602 try expect(args.@"1" == 12.34);
603 try expect(args.@"2");
604 try expect(args.@"3"[0] == 'h');
605 try expect(args.@"3"[1] == 'i');
606 }
607 };
608 try S.doTheTest();
609 comptime try S.doTheTest();
610}
611
612test "anonymous struct literal assigned to variable" {
613 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
614
615 var vec = .{ @as(i32, 22), @as(i32, 55), @as(i32, 99) };
616 try expect(vec.@"0" == 22);
617 try expect(vec.@"1" == 55);
618 try expect(vec.@"2" == 99);
619}
620
621test "struct with var field" {
622 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
623
624 const Point = struct {
625 x: anytype,
626 y: anytype,
627 };
628 const pt = Point{
629 .x = 1,
630 .y = 2,
631 };
632 try expect(pt.x == 1);
633 try expect(pt.y == 2);
634}
635
636test "comptime struct field" {
637 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
638
639 const T = struct {
640 a: i32,
641 comptime b: i32 = 1234,
642 };
643
644 var foo: T = undefined;
645 comptime try expect(foo.b == 1234);
646}
647
648test "anon struct literal field value initialized with fn call" {
649 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
650
651 const S = struct {
652 fn doTheTest() !void {
653 var x = .{foo()};
654 try expectEqualSlices(u8, x[0], "hi");
655 }
656 fn foo() []const u8 {
657 return "hi";
658 }
659 };
660 try S.doTheTest();
661 comptime try S.doTheTest();
662}
663
664test "struct with union field" {
665 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
666
667 const Value = struct {
668 ref: u32 = 2,
669 kind: union(enum) {
670 None: usize,
671 Bool: bool,
672 },
673 };
674
675 var True = Value{
676 .kind = .{ .Bool = true },
677 };
678 try expectEqual(@as(u32, 2), True.ref);
679 try expectEqual(true, True.kind.Bool);
680}
681
682test "type coercion of anon struct literal to struct" {
683 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
684
685 const S = struct {
686 const S2 = struct {
687 A: u32,
688 B: []const u8,
689 C: void,
690 D: Foo = .{},
691 };
692
693 const Foo = struct {
694 field: i32 = 1234,
695 };
696
697 fn doTheTest() !void {
698 var y: u32 = 42;
699 const t0 = .{ .A = 123, .B = "foo", .C = {} };
700 const t1 = .{ .A = y, .B = "foo", .C = {} };
701 const y0: S2 = t0;
702 var y1: S2 = t1;
703 try expect(y0.A == 123);
704 try expect(std.mem.eql(u8, y0.B, "foo"));
705 try expect(y0.C == {});
706 try expect(y0.D.field == 1234);
707 try expect(y1.A == y);
708 try expect(std.mem.eql(u8, y1.B, "foo"));
709 try expect(y1.C == {});
710 try expect(y1.D.field == 1234);
711 }
712 };
713 try S.doTheTest();
714 comptime try S.doTheTest();
715}
716
717test "type coercion of pointer to anon struct literal to pointer to struct" {
718 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
719
720 const S = struct {
721 const S2 = struct {
722 A: u32,
723 B: []const u8,
724 C: void,
725 D: Foo = .{},
726 };
727
728 const Foo = struct {
729 field: i32 = 1234,
730 };
731
732 fn doTheTest() !void {
733 var y: u32 = 42;
734 const t0 = &.{ .A = 123, .B = "foo", .C = {} };
735 const t1 = &.{ .A = y, .B = "foo", .C = {} };
736 const y0: *const S2 = t0;
737 var y1: *const S2 = t1;
738 try expect(y0.A == 123);
739 try expect(std.mem.eql(u8, y0.B, "foo"));
740 try expect(y0.C == {});
741 try expect(y0.D.field == 1234);
742 try expect(y1.A == y);
743 try expect(std.mem.eql(u8, y1.B, "foo"));
744 try expect(y1.C == {});
745 try expect(y1.D.field == 1234);
746 }
747 };
748 try S.doTheTest();
749 comptime try S.doTheTest();
750}
751
752test "packed struct with undefined initializers" {
753 const S = struct {
754 const P = packed struct {
755 a: u3,
756 _a: u3 = undefined,
757 b: u3,
758 _b: u3 = undefined,
759 c: u3,
760 _c: u3 = undefined,
761 };
762
763 fn doTheTest() !void {
764 var p: P = undefined;
765 p = P{ .a = 2, .b = 4, .c = 6 };
766 // Make sure the compiler doesn't touch the unprefixed fields.
767 // Use expect since i386-linux doesn't like expectEqual
768 try expect(p.a == 2);
769 try expect(p.b == 4);
770 try expect(p.c == 6);
771 }
772 };
773
774 try S.doTheTest();
775 comptime try S.doTheTest();
776}
777
778test "for loop over pointers to struct, getting field from struct pointer" {
779 // When enabling this test, be careful. I have observed it to pass when compiling
780 // stage2 alone, but when using stage1 with -fno-stage1 -fLLVM it fails.
781 // Maybe eyeball the LLVM that it generates and run in valgrind, both the compiler
782 // and the generated test at runtime.
783 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
784
785 const S = struct {
786 const Foo = struct {
787 name: []const u8,
788 };
789
790 var ok = true;
791
792 fn eql(a: []const u8) bool {
793 _ = a;
794 return true;
795 }
796
797 const ArrayList = struct {
798 fn toSlice(self: *ArrayList) []*Foo {
799 _ = self;
800 return @as([*]*Foo, undefined)[0..0];
801 }
802 };
803
804 fn doTheTest() !void {
805 var objects: ArrayList = undefined;
806
807 for (objects.toSlice()) |obj| {
808 if (eql(obj.name)) {
809 ok = false;
810 }
811 }
812
813 try expect(ok);
814 }
815 };
816 try S.doTheTest();
817}
test/behavior/struct_stage1.zig deleted-473
...@@ -1,473 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const native_endian = builtin.target.cpu.arch.endian();
4const expect = std.testing.expect;
5const expectEqual = std.testing.expectEqual;
6const expectEqualSlices = std.testing.expectEqualSlices;
7const maxInt = std.math.maxInt;
8
9const Foo32Bits = packed struct {
10 field: u24,
11 pad: u8,
12};
13
14const FooArray24Bits = packed struct {
15 a: u16,
16 b: [2]Foo32Bits,
17 c: u16,
18};
19
20// TODO revisit this test when doing https://github.com/ziglang/zig/issues/1512
21test "packed array 24bits" {
22 comptime {
23 try expect(@sizeOf([9]Foo32Bits) == 9 * 4);
24 try expect(@sizeOf(FooArray24Bits) == 2 + 2 * 4 + 2);
25 }
26
27 var bytes = [_]u8{0} ** (@sizeOf(FooArray24Bits) + 1);
28 bytes[bytes.len - 1] = 0xaa;
29 const ptr = &std.mem.bytesAsSlice(FooArray24Bits, bytes[0 .. bytes.len - 1])[0];
30 try expect(ptr.a == 0);
31 try expect(ptr.b[0].field == 0);
32 try expect(ptr.b[1].field == 0);
33 try expect(ptr.c == 0);
34
35 ptr.a = maxInt(u16);
36 try expect(ptr.a == maxInt(u16));
37 try expect(ptr.b[0].field == 0);
38 try expect(ptr.b[1].field == 0);
39 try expect(ptr.c == 0);
40
41 ptr.b[0].field = maxInt(u24);
42 try expect(ptr.a == maxInt(u16));
43 try expect(ptr.b[0].field == maxInt(u24));
44 try expect(ptr.b[1].field == 0);
45 try expect(ptr.c == 0);
46
47 ptr.b[1].field = maxInt(u24);
48 try expect(ptr.a == maxInt(u16));
49 try expect(ptr.b[0].field == maxInt(u24));
50 try expect(ptr.b[1].field == maxInt(u24));
51 try expect(ptr.c == 0);
52
53 ptr.c = maxInt(u16);
54 try expect(ptr.a == maxInt(u16));
55 try expect(ptr.b[0].field == maxInt(u24));
56 try expect(ptr.b[1].field == maxInt(u24));
57 try expect(ptr.c == maxInt(u16));
58
59 try expect(bytes[bytes.len - 1] == 0xaa);
60}
61
62const FooStructAligned = packed struct {
63 a: u8,
64 b: u8,
65};
66
67const FooArrayOfAligned = packed struct {
68 a: [2]FooStructAligned,
69};
70
71test "aligned array of packed struct" {
72 comptime {
73 try expect(@sizeOf(FooStructAligned) == 2);
74 try expect(@sizeOf(FooArrayOfAligned) == 2 * 2);
75 }
76
77 var bytes = [_]u8{0xbb} ** @sizeOf(FooArrayOfAligned);
78 const ptr = &std.mem.bytesAsSlice(FooArrayOfAligned, bytes[0..])[0];
79
80 try expect(ptr.a[0].a == 0xbb);
81 try expect(ptr.a[0].b == 0xbb);
82 try expect(ptr.a[1].a == 0xbb);
83 try expect(ptr.a[1].b == 0xbb);
84}
85
86test "pointer to packed struct member in a stack variable" {
87 const S = packed struct {
88 a: u2,
89 b: u2,
90 };
91
92 var s = S{ .a = 2, .b = 0 };
93 var b_ptr = &s.b;
94 try expect(s.b == 0);
95 b_ptr.* = 2;
96 try expect(s.b == 2);
97}
98
99test "non-byte-aligned array inside packed struct" {
100 const Foo = packed struct {
101 a: bool,
102 b: [0x16]u8,
103 };
104 const S = struct {
105 fn bar(slice: []const u8) !void {
106 try expectEqualSlices(u8, slice, "abcdefghijklmnopqurstu");
107 }
108 fn doTheTest() !void {
109 var foo = Foo{
110 .a = true,
111 .b = "abcdefghijklmnopqurstu".*,
112 };
113 const value = foo.b;
114 try bar(&value);
115 }
116 };
117 try S.doTheTest();
118 comptime try S.doTheTest();
119}
120
121test "packed struct with u0 field access" {
122 const S = packed struct {
123 f0: u0,
124 };
125 var s = S{ .f0 = 0 };
126 comptime try expect(s.f0 == 0);
127}
128
129const S0 = struct {
130 bar: S1,
131
132 pub const S1 = struct {
133 value: u8,
134 };
135
136 fn init() @This() {
137 return S0{ .bar = S1{ .value = 123 } };
138 }
139};
140
141var g_foo: S0 = S0.init();
142
143test "access to global struct fields" {
144 g_foo.bar.value = 42;
145 try expect(g_foo.bar.value == 42);
146}
147
148test "packed struct with fp fields" {
149 const S = packed struct {
150 data: [3]f32,
151
152 pub fn frob(self: *@This()) void {
153 self.data[0] += self.data[1] + self.data[2];
154 self.data[1] += self.data[0] + self.data[2];
155 self.data[2] += self.data[0] + self.data[1];
156 }
157 };
158
159 var s: S = undefined;
160 s.data[0] = 1.0;
161 s.data[1] = 2.0;
162 s.data[2] = 3.0;
163 s.frob();
164 try expectEqual(@as(f32, 6.0), s.data[0]);
165 try expectEqual(@as(f32, 11.0), s.data[1]);
166 try expectEqual(@as(f32, 20.0), s.data[2]);
167}
168
169test "fn with C calling convention returns struct by value" {
170 const S = struct {
171 fn entry() !void {
172 var x = makeBar(10);
173 try expectEqual(@as(i32, 10), x.handle);
174 }
175
176 const ExternBar = extern struct {
177 handle: i32,
178 };
179
180 fn makeBar(t: i32) callconv(.C) ExternBar {
181 return ExternBar{
182 .handle = t,
183 };
184 }
185 };
186 try S.entry();
187 comptime try S.entry();
188}
189
190test "non-packed struct with u128 entry in union" {
191 const U = union(enum) {
192 Num: u128,
193 Void,
194 };
195
196 const S = struct {
197 f1: U,
198 f2: U,
199 };
200
201 var sx: S = undefined;
202 var s = &sx;
203 try std.testing.expect(@ptrToInt(&s.f2) - @ptrToInt(&s.f1) == @offsetOf(S, "f2"));
204 var v2 = U{ .Num = 123 };
205 s.f2 = v2;
206 try std.testing.expect(s.f2.Num == 123);
207}
208
209test "packed struct field passed to generic function" {
210 const S = struct {
211 const P = packed struct {
212 b: u5,
213 g: u5,
214 r: u5,
215 a: u1,
216 };
217
218 fn genericReadPackedField(ptr: anytype) u5 {
219 return ptr.*;
220 }
221 };
222
223 var p: S.P = undefined;
224 p.b = 29;
225 var loaded = S.genericReadPackedField(&p.b);
226 try expect(loaded == 29);
227}
228
229test "anonymous struct literal syntax" {
230 const S = struct {
231 const Point = struct {
232 x: i32,
233 y: i32,
234 };
235
236 fn doTheTest() !void {
237 var p: Point = .{
238 .x = 1,
239 .y = 2,
240 };
241 try expect(p.x == 1);
242 try expect(p.y == 2);
243 }
244 };
245 try S.doTheTest();
246 comptime try S.doTheTest();
247}
248
249test "fully anonymous struct" {
250 const S = struct {
251 fn doTheTest() !void {
252 try dump(.{
253 .int = @as(u32, 1234),
254 .float = @as(f64, 12.34),
255 .b = true,
256 .s = "hi",
257 });
258 }
259 fn dump(args: anytype) !void {
260 try expect(args.int == 1234);
261 try expect(args.float == 12.34);
262 try expect(args.b);
263 try expect(args.s[0] == 'h');
264 try expect(args.s[1] == 'i');
265 }
266 };
267 try S.doTheTest();
268 comptime try S.doTheTest();
269}
270
271test "fully anonymous list literal" {
272 const S = struct {
273 fn doTheTest() !void {
274 try dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" });
275 }
276 fn dump(args: anytype) !void {
277 try expect(args.@"0" == 1234);
278 try expect(args.@"1" == 12.34);
279 try expect(args.@"2");
280 try expect(args.@"3"[0] == 'h');
281 try expect(args.@"3"[1] == 'i');
282 }
283 };
284 try S.doTheTest();
285 comptime try S.doTheTest();
286}
287
288test "anonymous struct literal assigned to variable" {
289 var vec = .{ @as(i32, 22), @as(i32, 55), @as(i32, 99) };
290 try expect(vec.@"0" == 22);
291 try expect(vec.@"1" == 55);
292 try expect(vec.@"2" == 99);
293}
294
295test "struct with var field" {
296 const Point = struct {
297 x: anytype,
298 y: anytype,
299 };
300 const pt = Point{
301 .x = 1,
302 .y = 2,
303 };
304 try expect(pt.x == 1);
305 try expect(pt.y == 2);
306}
307
308test "comptime struct field" {
309 const T = struct {
310 a: i32,
311 comptime b: i32 = 1234,
312 };
313
314 var foo: T = undefined;
315 comptime try expect(foo.b == 1234);
316}
317
318test "anon struct literal field value initialized with fn call" {
319 const S = struct {
320 fn doTheTest() !void {
321 var x = .{foo()};
322 try expectEqualSlices(u8, x[0], "hi");
323 }
324 fn foo() []const u8 {
325 return "hi";
326 }
327 };
328 try S.doTheTest();
329 comptime try S.doTheTest();
330}
331
332test "struct with union field" {
333 const Value = struct {
334 ref: u32 = 2,
335 kind: union(enum) {
336 None: usize,
337 Bool: bool,
338 },
339 };
340
341 var True = Value{
342 .kind = .{ .Bool = true },
343 };
344 try expectEqual(@as(u32, 2), True.ref);
345 try expectEqual(true, True.kind.Bool);
346}
347
348test "type coercion of anon struct literal to struct" {
349 const S = struct {
350 const S2 = struct {
351 A: u32,
352 B: []const u8,
353 C: void,
354 D: Foo = .{},
355 };
356
357 const Foo = struct {
358 field: i32 = 1234,
359 };
360
361 fn doTheTest() !void {
362 var y: u32 = 42;
363 const t0 = .{ .A = 123, .B = "foo", .C = {} };
364 const t1 = .{ .A = y, .B = "foo", .C = {} };
365 const y0: S2 = t0;
366 var y1: S2 = t1;
367 try expect(y0.A == 123);
368 try expect(std.mem.eql(u8, y0.B, "foo"));
369 try expect(y0.C == {});
370 try expect(y0.D.field == 1234);
371 try expect(y1.A == y);
372 try expect(std.mem.eql(u8, y1.B, "foo"));
373 try expect(y1.C == {});
374 try expect(y1.D.field == 1234);
375 }
376 };
377 try S.doTheTest();
378 comptime try S.doTheTest();
379}
380
381test "type coercion of pointer to anon struct literal to pointer to struct" {
382 const S = struct {
383 const S2 = struct {
384 A: u32,
385 B: []const u8,
386 C: void,
387 D: Foo = .{},
388 };
389
390 const Foo = struct {
391 field: i32 = 1234,
392 };
393
394 fn doTheTest() !void {
395 var y: u32 = 42;
396 const t0 = &.{ .A = 123, .B = "foo", .C = {} };
397 const t1 = &.{ .A = y, .B = "foo", .C = {} };
398 const y0: *const S2 = t0;
399 var y1: *const S2 = t1;
400 try expect(y0.A == 123);
401 try expect(std.mem.eql(u8, y0.B, "foo"));
402 try expect(y0.C == {});
403 try expect(y0.D.field == 1234);
404 try expect(y1.A == y);
405 try expect(std.mem.eql(u8, y1.B, "foo"));
406 try expect(y1.C == {});
407 try expect(y1.D.field == 1234);
408 }
409 };
410 try S.doTheTest();
411 comptime try S.doTheTest();
412}
413
414test "packed struct with undefined initializers" {
415 const S = struct {
416 const P = packed struct {
417 a: u3,
418 _a: u3 = undefined,
419 b: u3,
420 _b: u3 = undefined,
421 c: u3,
422 _c: u3 = undefined,
423 };
424
425 fn doTheTest() !void {
426 var p: P = undefined;
427 p = P{ .a = 2, .b = 4, .c = 6 };
428 // Make sure the compiler doesn't touch the unprefixed fields.
429 // Use expect since i386-linux doesn't like expectEqual
430 try expect(p.a == 2);
431 try expect(p.b == 4);
432 try expect(p.c == 6);
433 }
434 };
435
436 try S.doTheTest();
437 comptime try S.doTheTest();
438}
439
440test "for loop over pointers to struct, getting field from struct pointer" {
441 const S = struct {
442 const Foo = struct {
443 name: []const u8,
444 };
445
446 var ok = true;
447
448 fn eql(a: []const u8) bool {
449 _ = a;
450 return true;
451 }
452
453 const ArrayList = struct {
454 fn toSlice(self: *ArrayList) []*Foo {
455 _ = self;
456 return @as([*]*Foo, undefined)[0..0];
457 }
458 };
459
460 fn doTheTest() !void {
461 var objects: ArrayList = undefined;
462
463 for (objects.toSlice()) |obj| {
464 if (eql(obj.name)) {
465 ok = false;
466 }
467 }
468
469 try expect(ok);
470 }
471 };
472 try S.doTheTest();
473}
test/behavior/translate_c_macros.zig+31
...@@ -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;
...@@ -16,3 +17,33 @@ test "casting to void with a macro" {...@@ -16,3 +17,33 @@ test "casting to void with a macro" {
16 h.IGNORE_ME_9(42);17 h.IGNORE_ME_9(42);
17 h.IGNORE_ME_10(42);18 h.IGNORE_ME_10(42);
18}19}
20
21test "initializer list expression" {
22 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
23
24 try expectEqual(h.Color{
25 .r = 200,
26 .g = 200,
27 .b = 200,
28 .a = 255,
29 }, h.LIGHTGRAY);
30}
31
32test "sizeof in macros" {
33 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
34
35 try expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF(u32));
36 try expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF2(u32));
37}
38
39test "reference to a struct type" {
40 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
41
42 try expectEqual(@sizeOf(h.struct_Foo), h.SIZE_OF_FOO);
43}
44
45test "cast negative integer to pointer" {
46 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
47
48 try expectEqual(@intToPtr(?*anyopaque, @bitCast(usize, @as(isize, -1))), h.MAP_FAILED);
49}
test/behavior/translate_c_macros_stage1.zig deleted-27
...@@ -1,27 +0,0 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;
4
5const h = @cImport(@cInclude("behavior/translate_c_macros.h"));
6
7test "initializer list expression" {
8 try expectEqual(h.Color{
9 .r = 200,
10 .g = 200,
11 .b = 200,
12 .a = 255,
13 }, h.LIGHTGRAY);
14}
15
16test "sizeof in macros" {
17 try expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF(u32));
18 try expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF2(u32));
19}
20
21test "reference to a struct type" {
22 try expectEqual(@sizeOf(h.struct_Foo), h.SIZE_OF_FOO);
23}
24
25test "cast negative integer to pointer" {
26 try expectEqual(@intToPtr(?*anyopaque, @bitCast(usize, @as(isize, -1))), h.MAP_FAILED);
27}