From 692c254336da71cbe21aaf9fbc21240fd1269b95 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 30 Nov 2021 00:19:37 -0700 Subject: [PATCH] Revert "I found some more passing behavior tests" This reverts commit 0a9b4d092f58595888f9e4be8ef683b2ed8a0da1. Hm, these are all passing for me locally. I'll have to do some troubleshooting to figure out which one(s) are failing on the CI. --- test/behavior.zig | 34 +++--- test/behavior/struct.zig | 141 ------------------------ test/behavior/struct_llvm.zig | 115 ++++++++++--------- test/behavior/struct_stage1.zig | 139 +++++++++++++++++++++++ test/behavior/usingnamespace.zig | 40 ------- test/behavior/usingnamespace_stage1.zig | 41 +++++++ 6 files changed, 262 insertions(+), 248 deletions(-) create mode 100644 test/behavior/usingnamespace_stage1.zig diff --git a/test/behavior.zig b/test/behavior.zig index 923c54b400..b251c418e7 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -10,41 +10,32 @@ test { _ = @import("behavior/bugs/655.zig"); _ = @import("behavior/bugs/679.zig"); _ = @import("behavior/bugs/704.zig"); - _ = @import("behavior/bugs/1111.zig"); _ = @import("behavior/bugs/1486.zig"); _ = @import("behavior/bugs/2346.zig"); _ = @import("behavior/bugs/2692.zig"); _ = @import("behavior/bugs/2889.zig"); - _ = @import("behavior/bugs/3046.zig"); _ = @import("behavior/bugs/3586.zig"); _ = @import("behavior/bugs/4560.zig"); _ = @import("behavior/bugs/4769_a.zig"); _ = @import("behavior/bugs/4769_b.zig"); - _ = @import("behavior/bugs/4954.zig"); _ = @import("behavior/bugs/6850.zig"); - _ = @import("behavior/byval_arg_var.zig"); _ = @import("behavior/call.zig"); _ = @import("behavior/cast.zig"); _ = @import("behavior/defer.zig"); _ = @import("behavior/enum.zig"); _ = @import("behavior/error.zig"); - _ = @import("behavior/fn_in_struct_in_comptime.zig"); _ = @import("behavior/generics.zig"); _ = @import("behavior/hasdecl.zig"); _ = @import("behavior/hasfield.zig"); _ = @import("behavior/if.zig"); _ = @import("behavior/import.zig"); - _ = @import("behavior/incomplete_struct_param_tld.zig"); _ = @import("behavior/int128.zig"); - _ = @import("behavior/inttoptr.zig"); _ = @import("behavior/member_func.zig"); _ = @import("behavior/null.zig"); _ = @import("behavior/optional.zig"); _ = @import("behavior/pointers.zig"); _ = @import("behavior/ptrcast.zig"); _ = @import("behavior/pub_enum.zig"); - _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig"); - _ = @import("behavior/slice_sentinel_comptime.zig"); _ = @import("behavior/struct.zig"); _ = @import("behavior/this.zig"); _ = @import("behavior/translate_c_macros.zig"); @@ -56,22 +47,17 @@ test { if (builtin.object_format != .c) { // Tests that pass for stage1 and stage2 but not the C backend. _ = @import("behavior/align_llvm.zig"); - _ = @import("behavior/alignof.zig"); _ = @import("behavior/array.zig"); _ = @import("behavior/atomics.zig"); _ = @import("behavior/basic_llvm.zig"); _ = @import("behavior/bugs/394.zig"); - _ = @import("behavior/bugs/656.zig"); _ = @import("behavior/bugs/1277.zig"); - _ = @import("behavior/bugs/1381.zig"); _ = @import("behavior/bugs/1500.zig"); _ = @import("behavior/bugs/1741.zig"); _ = @import("behavior/bugs/2006.zig"); - _ = @import("behavior/bugs/2578.zig"); - _ = @import("behavior/bugs/3007.zig"); _ = @import("behavior/bugs/3112.zig"); - _ = @import("behavior/bugs/7250.zig"); _ = @import("behavior/cast_llvm.zig"); + _ = @import("behavior/error.zig"); _ = @import("behavior/eval.zig"); _ = @import("behavior/floatop.zig"); _ = @import("behavior/fn.zig"); @@ -79,7 +65,6 @@ test { _ = @import("behavior/generics_llvm.zig"); _ = @import("behavior/math.zig"); _ = @import("behavior/maximum_minimum.zig"); - _ = @import("behavior/namespace_depends_on_compile_var.zig"); _ = @import("behavior/null_llvm.zig"); _ = @import("behavior/optional_llvm.zig"); _ = @import("behavior/popcount.zig"); @@ -99,6 +84,7 @@ test { _ = @import("behavior/slice_stage2.zig"); } else { _ = @import("behavior/align_stage1.zig"); + _ = @import("behavior/alignof.zig"); _ = @import("behavior/array_stage1.zig"); if (builtin.os.tag != .wasi) { _ = @import("behavior/asm.zig"); @@ -110,15 +96,18 @@ test { _ = @import("behavior/bitreverse.zig"); _ = @import("behavior/bugs/421.zig"); _ = @import("behavior/bugs/529.zig"); + _ = @import("behavior/bugs/656.zig"); _ = @import("behavior/bugs/718.zig"); _ = @import("behavior/bugs/726.zig"); _ = @import("behavior/bugs/828.zig"); _ = @import("behavior/bugs/920.zig"); _ = @import("behavior/bugs/1025.zig"); _ = @import("behavior/bugs/1076.zig"); + _ = @import("behavior/bugs/1111.zig"); _ = @import("behavior/bugs/1120.zig"); _ = @import("behavior/bugs/1310.zig"); _ = @import("behavior/bugs/1322.zig"); + _ = @import("behavior/bugs/1381.zig"); _ = @import("behavior/bugs/1421.zig"); _ = @import("behavior/bugs/1442.zig"); _ = @import("behavior/bugs/1607.zig"); @@ -126,11 +115,15 @@ test { _ = @import("behavior/bugs/1851.zig"); _ = @import("behavior/bugs/1914.zig"); _ = @import("behavior/bugs/2114.zig"); + _ = @import("behavior/bugs/2578.zig"); + _ = @import("behavior/bugs/3007.zig"); + _ = @import("behavior/bugs/3046.zig"); _ = @import("behavior/bugs/3367.zig"); _ = @import("behavior/bugs/3384.zig"); _ = @import("behavior/bugs/3742.zig"); _ = @import("behavior/bugs/3779.zig"); _ = @import("behavior/bugs/4328.zig"); + _ = @import("behavior/bugs/4954.zig"); _ = @import("behavior/bugs/5398.zig"); _ = @import("behavior/bugs/5413.zig"); _ = @import("behavior/bugs/5474.zig"); @@ -140,10 +133,12 @@ test { _ = @import("behavior/bugs/7003.zig"); _ = @import("behavior/bugs/7027.zig"); _ = @import("behavior/bugs/7047.zig"); + _ = @import("behavior/bugs/7250.zig"); _ = @import("behavior/bugs/9584.zig"); _ = @import("behavior/bugs/9967.zig"); _ = @import("behavior/bugs/10147.zig"); _ = @import("behavior/byteswap.zig"); + _ = @import("behavior/byval_arg_var.zig"); _ = @import("behavior/call_stage1.zig"); _ = @import("behavior/cast_stage1.zig"); _ = @import("behavior/const_slice_child.zig"); @@ -155,22 +150,28 @@ test { _ = @import("behavior/floatop_stage1.zig"); _ = @import("behavior/fn_stage1.zig"); _ = @import("behavior/fn_delegation.zig"); + _ = @import("behavior/fn_in_struct_in_comptime.zig"); _ = @import("behavior/for_stage1.zig"); _ = @import("behavior/if_stage1.zig"); + _ = @import("behavior/incomplete_struct_param_tld.zig"); + _ = @import("behavior/inttoptr.zig"); _ = @import("behavior/ir_block_deps.zig"); _ = @import("behavior/math_stage1.zig"); _ = @import("behavior/merge_error_sets.zig"); _ = @import("behavior/misc.zig"); _ = @import("behavior/muladd.zig"); + _ = @import("behavior/namespace_depends_on_compile_var.zig"); _ = @import("behavior/null_stage1.zig"); _ = @import("behavior/optional_stage1.zig"); _ = @import("behavior/pointers_stage1.zig"); _ = @import("behavior/popcount_stage1.zig"); _ = @import("behavior/ptrcast_stage1.zig"); + _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig"); _ = @import("behavior/reflection.zig"); _ = @import("behavior/select.zig"); _ = @import("behavior/shuffle.zig"); _ = @import("behavior/sizeof_and_typeof_stage1.zig"); + _ = @import("behavior/slice_sentinel_comptime.zig"); _ = @import("behavior/slice_stage1.zig"); _ = @import("behavior/struct_contains_null_ptr_itself.zig"); _ = @import("behavior/struct_contains_slice_of_itself.zig"); @@ -185,6 +186,7 @@ test { _ = @import("behavior/typename.zig"); _ = @import("behavior/union_stage1.zig"); _ = @import("behavior/union_with_members.zig"); + _ = @import("behavior/usingnamespace_stage1.zig"); _ = @import("behavior/var_args.zig"); _ = @import("behavior/vector.zig"); if (builtin.target.cpu.arch == .wasm32) { diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 1e47877fd6..eeaa80ed69 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -6,55 +6,12 @@ const expectEqual = std.testing.expectEqual; const expectEqualSlices = std.testing.expectEqualSlices; const maxInt = std.math.maxInt; -top_level_field: i32, - -test "top level fields" { - var instance = @This(){ - .top_level_field = 1234, - }; - instance.top_level_field += 1; - try expect(@as(i32, 1235) == instance.top_level_field); -} - const StructWithNoFields = struct { fn add(a: i32, b: i32) i32 { return a + b; } }; -const StructFoo = struct { - a: i32, - b: bool, - c: f32, -}; - -test "structs" { - var foo: StructFoo = undefined; - @memset(@ptrCast([*]u8, &foo), 0, @sizeOf(StructFoo)); - foo.a += 1; - foo.b = foo.a == 1; - try testFoo(foo); - testMutation(&foo); - try expect(foo.c == 100); -} -fn testFoo(foo: StructFoo) !void { - try expect(foo.b); -} -fn testMutation(foo: *StructFoo) void { - foo.c = 100; -} - -test "struct byval assign" { - var foo1: StructFoo = undefined; - var foo2: StructFoo = undefined; - - foo1.a = 1234; - foo2.a = 0; - try expect(foo2.a == 0); - foo2 = foo1; - try expect(foo2.a == 1234); -} - test "call struct static method" { const result = StructWithNoFields.add(3, 4); try expect(result == 7); @@ -84,23 +41,6 @@ const Val = struct { x: i32, }; -test "fn call of struct field" { - const Foo = struct { - ptr: fn () i32, - }; - const S = struct { - fn aFunc() i32 { - return 13; - } - - fn callStructField(foo: Foo) i32 { - return foo.ptr(); - } - }; - - try expect(S.callStructField(Foo{ .ptr = S.aFunc }) == 13); -} - test "struct initializer" { const val = Val{ .x = 42 }; try expect(val.x == 42); @@ -118,84 +58,3 @@ test "call member function directly" { const result = MemberFnTestFoo.member(instance); try expect(result == 1234); } - -test "store member function in variable" { - const instance = MemberFnTestFoo{ .x = 1234 }; - const memberFn = MemberFnTestFoo.member; - const result = memberFn(instance); - try expect(result == 1234); -} - -test "member functions" { - const r = MemberFnRand{ .seed = 1234 }; - try expect(r.getSeed() == 1234); -} -const MemberFnRand = struct { - seed: u32, - pub fn getSeed(r: *const MemberFnRand) u32 { - return r.seed; - } -}; - -test "return struct byval from function" { - const bar = makeBar2(1234, 5678); - try expect(bar.y == 5678); -} -const Bar = struct { - x: i32, - y: i32, -}; -fn makeBar2(x: i32, y: i32) Bar { - return Bar{ - .x = x, - .y = y, - }; -} - -test "call method with mutable reference to struct with no fields" { - const S = struct { - fn doC(s: *const @This()) bool { - _ = s; - return true; - } - fn do(s: *@This()) bool { - _ = s; - return true; - } - }; - - var s = S{}; - try expect(S.doC(&s)); - try expect(s.doC()); - try expect(S.do(&s)); - try expect(s.do()); -} - -test "usingnamespace within struct scope" { - const S = struct { - usingnamespace struct { - pub fn inner() i32 { - return 42; - } - }; - }; - try expect(@as(i32, 42) == S.inner()); -} - -test "struct field init with catch" { - const S = struct { - fn doTheTest() !void { - var x: anyerror!isize = 1; - var req = Foo{ - .field = x catch undefined, - }; - try expect(req.field == 1); - } - - pub const Foo = extern struct { - field: isize, - }; - }; - try S.doTheTest(); - comptime try S.doTheTest(); -} diff --git a/test/behavior/struct_llvm.zig b/test/behavior/struct_llvm.zig index 35c71fe7a2..a809905cef 100644 --- a/test/behavior/struct_llvm.zig +++ b/test/behavior/struct_llvm.zig @@ -6,6 +6,44 @@ const expectEqual = std.testing.expectEqual; const expectEqualSlices = std.testing.expectEqualSlices; const maxInt = std.math.maxInt; +const StructWithNoFields = struct { + fn add(a: i32, b: i32) i32 { + return a + b; + } +}; + +const StructFoo = struct { + a: i32, + b: bool, + c: f32, +}; +test "structs" { + var foo: StructFoo = undefined; + @memset(@ptrCast([*]u8, &foo), 0, @sizeOf(StructFoo)); + foo.a += 1; + foo.b = foo.a == 1; + try testFoo(foo); + testMutation(&foo); + try expect(foo.c == 100); +} +fn testFoo(foo: StructFoo) !void { + try expect(foo.b); +} +fn testMutation(foo: *StructFoo) void { + foo.c = 100; +} + +test "struct byval assign" { + var foo1: StructFoo = undefined; + var foo2: StructFoo = undefined; + + foo1.a = 1234; + foo2.a = 0; + try expect(foo2.a == 0); + foo2 = foo1; + try expect(foo2.a == 1234); +} + const Node = struct { val: Val, next: *Node, @@ -43,6 +81,32 @@ const VoidStructFieldsFoo = struct { c: void, }; +test "member functions" { + const r = MemberFnRand{ .seed = 1234 }; + try expect(r.getSeed() == 1234); +} +const MemberFnRand = struct { + seed: u32, + pub fn getSeed(r: *const MemberFnRand) u32 { + return r.seed; + } +}; + +test "return struct byval from function" { + const bar = makeBar2(1234, 5678); + try expect(bar.y == 5678); +} +const Bar = struct { + x: i32, + y: i32, +}; +fn makeBar2(x: i32, y: i32) Bar { + return Bar{ + .x = x, + .y = y, + }; +} + test "return empty struct from fn" { _ = testReturnEmptyStructFromFn(); } @@ -50,54 +114,3 @@ const EmptyStruct2 = struct {}; fn testReturnEmptyStructFromFn() EmptyStruct2 { return EmptyStruct2{}; } - -test "pass slice of empty struct to fn" { - try expect(testPassSliceOfEmptyStructToFn(&[_]EmptyStruct2{EmptyStruct2{}}) == 1); -} -fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) usize { - return slice.len; -} - -test "for loop over pointers to struct, getting field from struct pointer" { - const S = struct { - const Foo = struct { - name: []const u8, - }; - - var ok = true; - - fn eql(a: []const u8) bool { - _ = a; - return true; - } - - const ArrayList = struct { - fn toSlice(self: *ArrayList) []*Foo { - _ = self; - return @as([*]*Foo, undefined)[0..0]; - } - }; - - fn doTheTest() !void { - var objects: ArrayList = undefined; - - for (objects.toSlice()) |obj| { - if (eql(obj.name)) { - ok = false; - } - } - - try expect(ok); - } - }; - try S.doTheTest(); -} - -test "self-referencing struct via array member" { - const T = struct { - children: [1]*@This(), - }; - var x: T = undefined; - x = T{ .children = .{&x} }; - try expect(x.children[0] == &x); -} diff --git a/test/behavior/struct_stage1.zig b/test/behavior/struct_stage1.zig index 4b78bd13d3..a04e54e89b 100644 --- a/test/behavior/struct_stage1.zig +++ b/test/behavior/struct_stage1.zig @@ -6,6 +6,16 @@ const expectEqual = std.testing.expectEqual; const expectEqualSlices = std.testing.expectEqualSlices; const maxInt = std.math.maxInt; +top_level_field: i32, + +test "top level fields" { + var instance = @This(){ + .top_level_field = 1234, + }; + instance.top_level_field += 1; + try expectEqual(@as(i32, 1235), instance.top_level_field); +} + const StructFoo = struct { a: i32, b: bool, @@ -21,6 +31,36 @@ const Val = struct { x: i32, }; +test "fn call of struct field" { + const Foo = struct { + ptr: fn () i32, + }; + const S = struct { + fn aFunc() i32 { + return 13; + } + + fn callStructField(foo: Foo) i32 { + return foo.ptr(); + } + }; + + try expect(S.callStructField(Foo{ .ptr = S.aFunc }) == 13); +} + +const MemberFnTestFoo = struct { + x: i32, + fn member(foo: MemberFnTestFoo) i32 { + return foo.x; + } +}; +test "store member function in variable" { + const instance = MemberFnTestFoo{ .x = 1234 }; + const memberFn = MemberFnTestFoo.member; + const result = memberFn(instance); + try expect(result == 1234); +} + test "empty struct method call" { const es = EmptyStruct{}; try expect(es.method() == 1234); @@ -37,6 +77,13 @@ fn testReturnEmptyStructFromFn() EmptyStruct2 { return EmptyStruct2{}; } +test "pass slice of empty struct to fn" { + try expect(testPassSliceOfEmptyStructToFn(&[_]EmptyStruct2{EmptyStruct2{}}) == 1); +} +fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) usize { + return slice.len; +} + const APackedStruct = packed struct { x: u8, y: u8, @@ -285,6 +332,25 @@ fn alloc(comptime T: type) []T { return &[_]T{}; } +test "call method with mutable reference to struct with no fields" { + const S = struct { + fn doC(s: *const @This()) bool { + _ = s; + return true; + } + fn do(s: *@This()) bool { + _ = s; + return true; + } + }; + + var s = S{}; + try expect(S.doC(&s)); + try expect(s.doC()); + try expect(S.do(&s)); + try expect(s.do()); +} + test "implicit cast packed struct field to const ptr" { const LevelUpMove = packed struct { move_id: u9, @@ -384,6 +450,17 @@ test "packed struct with fp fields" { try expectEqual(@as(f32, 20.0), s.data[2]); } +test "use within struct scope" { + const S = struct { + usingnamespace struct { + pub fn inner() i32 { + return 42; + } + }; + }; + try expectEqual(@as(i32, 42), S.inner()); +} + test "default struct initialization fields" { const S = struct { a: i32 = 1234, @@ -424,6 +501,41 @@ test "fn with C calling convention returns struct by value" { comptime try S.entry(); } +test "for loop over pointers to struct, getting field from struct pointer" { + const S = struct { + const Foo = struct { + name: []const u8, + }; + + var ok = true; + + fn eql(a: []const u8) bool { + _ = a; + return true; + } + + const ArrayList = struct { + fn toSlice(self: *ArrayList) []*Foo { + _ = self; + return @as([*]*Foo, undefined)[0..0]; + } + }; + + fn doTheTest() !void { + var objects: ArrayList = undefined; + + for (objects.toSlice()) |obj| { + if (eql(obj.name)) { + ok = false; + } + } + + try expect(ok); + } + }; + try S.doTheTest(); +} + test "zero-bit field in packed struct" { const S = packed struct { x: u10, @@ -433,6 +545,24 @@ test "zero-bit field in packed struct" { _ = x; } +test "struct field init with catch" { + const S = struct { + fn doTheTest() !void { + var x: anyerror!isize = 1; + var req = Foo{ + .field = x catch undefined, + }; + try expect(req.field == 1); + } + + pub const Foo = extern struct { + field: isize, + }; + }; + try S.doTheTest(); + comptime try S.doTheTest(); +} + test "packed struct with non-ABI-aligned field" { const S = packed struct { x: u9, @@ -587,6 +717,15 @@ test "anon struct literal field value initialized with fn call" { comptime try S.doTheTest(); } +test "self-referencing struct via array member" { + const T = struct { + children: [1]*@This(), + }; + var x: T = undefined; + x = T{ .children = .{&x} }; + try expect(x.children[0] == &x); +} + test "struct with union field" { const Value = struct { ref: u32 = 2, diff --git a/test/behavior/usingnamespace.zig b/test/behavior/usingnamespace.zig index ad47762c16..e819566002 100644 --- a/test/behavior/usingnamespace.zig +++ b/test/behavior/usingnamespace.zig @@ -1,5 +1,4 @@ const std = @import("std"); -const expect = std.testing.expect; const A = struct { pub const B = bool; @@ -12,42 +11,3 @@ const C = struct { test "basic usingnamespace" { try std.testing.expect(C.B == bool); } - -fn Foo(comptime T: type) type { - return struct { - usingnamespace T; - }; -} - -test "usingnamespace inside a generic struct" { - const std2 = Foo(std); - const testing2 = Foo(std.testing); - try std2.testing.expect(true); - try testing2.expect(true); -} - -usingnamespace struct { - pub const foo = 42; -}; - -test "usingnamespace does not redeclare an imported variable" { - comptime try std.testing.expect(@This().foo == 42); -} - -usingnamespace @import("usingnamespace/foo.zig"); -test "usingnamespace omits mixing in private functions" { - try expect(@This().privateFunction()); - try expect(!@This().printText()); -} -fn privateFunction() bool { - return true; -} - -test { - _ = @import("usingnamespace/import_segregation.zig"); -} - -usingnamespace @import("usingnamespace/a.zig"); -test "two files usingnamespace import each other" { - try expect(@This().ok()); -} diff --git a/test/behavior/usingnamespace_stage1.zig b/test/behavior/usingnamespace_stage1.zig new file mode 100644 index 0000000000..142df21549 --- /dev/null +++ b/test/behavior/usingnamespace_stage1.zig @@ -0,0 +1,41 @@ +const std = @import("std"); +const expect = std.testing.expect; + +fn Foo(comptime T: type) type { + return struct { + usingnamespace T; + }; +} + +test "usingnamespace inside a generic struct" { + const std2 = Foo(std); + const testing2 = Foo(std.testing); + try std2.testing.expect(true); + try testing2.expect(true); +} + +usingnamespace struct { + pub const foo = 42; +}; + +test "usingnamespace does not redeclare an imported variable" { + comptime try std.testing.expect(@This().foo == 42); +} + +usingnamespace @import("usingnamespace/foo.zig"); +test "usingnamespace omits mixing in private functions" { + try expect(@This().privateFunction()); + try expect(!@This().printText()); +} +fn privateFunction() bool { + return true; +} + +test { + _ = @import("usingnamespace/import_segregation.zig"); +} + +usingnamespace @import("usingnamespace/a.zig"); +test "two files usingnamespace import each other" { + try expect(@This().ok()); +}