diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 1ebca942d5..2c58ee56f8 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -2341,10 +2341,33 @@ pub const FuncGen = struct { } fn airWrapOptional(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { - if (self.liveness.isUnused(inst)) - return null; + if (self.liveness.isUnused(inst)) return null; - return self.todo("implement llvm codegen for 'airWrapOptional'", .{}); + const ty_op = self.air.instructions.items(.data)[inst].ty_op; + const operand_ty = self.air.typeOf(ty_op.operand); + const non_null_bit = self.context.intType(1).constAllOnes(); + if (!operand_ty.hasCodeGenBits()) return non_null_bit; + const operand = try self.resolveInst(ty_op.operand); + const optional_ty = self.air.typeOfIndex(inst); + if (optional_ty.isPtrLikeOptional()) return operand; + const llvm_optional_ty = try self.dg.llvmType(optional_ty); + if (isByRef(optional_ty)) { + const optional_ptr = self.buildAlloca(llvm_optional_ty); + const payload_ptr = self.builder.buildStructGEP(optional_ptr, 0, ""); + var buf: Type.Payload.ElemType = undefined; + const payload_ty = operand_ty.optionalChild(&buf); + var ptr_ty_payload: Type.Payload.ElemType = .{ + .base = .{ .tag = .single_mut_pointer }, + .data = payload_ty, + }; + const payload_ptr_ty = Type.initPayload(&ptr_ty_payload.base); + self.store(payload_ptr, payload_ptr_ty, operand, .NotAtomic); + const non_null_ptr = self.builder.buildStructGEP(optional_ptr, 1, ""); + _ = self.builder.buildStore(non_null_bit, non_null_ptr); + return optional_ptr; + } + const partial = self.builder.buildInsertValue(llvm_optional_ty.getUndef(), operand, 0, ""); + return self.builder.buildInsertValue(partial, non_null_bit, 1, ""); } fn airWrapErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { diff --git a/test/behavior.zig b/test/behavior.zig index 925d5a65f5..5ed20fe76a 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -28,6 +28,7 @@ test { _ = @import("behavior/member_func.zig"); _ = @import("behavior/optional.zig"); _ = @import("behavior/pointers.zig"); + _ = @import("behavior/pub_enum.zig"); _ = @import("behavior/slice.zig"); _ = @import("behavior/sizeof_and_typeof.zig"); _ = @import("behavior/struct.zig"); @@ -140,7 +141,6 @@ test { _ = @import("behavior/pointers_stage1.zig"); _ = @import("behavior/popcount.zig"); _ = @import("behavior/ptrcast.zig"); - _ = @import("behavior/pub_enum.zig"); _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig"); _ = @import("behavior/reflection.zig"); { diff --git a/test/behavior/basic.zig b/test/behavior/basic.zig index 33e4c6fd8d..23b0970191 100644 --- a/test/behavior/basic.zig +++ b/test/behavior/basic.zig @@ -411,3 +411,38 @@ test "use of declaration with same name as primitive" { const c: @"u8" = 300; try expect(c == 300); } + +fn emptyFn() void {} + +test "constant equal function pointers" { + const alias = emptyFn; + try expect(comptime x: { + break :x emptyFn == alias; + }); +} + +test "multiline string literal is null terminated" { + const s1 = + \\one + \\two) + \\three + ; + const s2 = "one\ntwo)\nthree"; + try expect(std.cstr.cmp(s1, s2) == 0); +} + +test "self reference through fn ptr field" { + const S = struct { + const A = struct { + f: fn (A) u8, + }; + + fn foo(a: A) u8 { + _ = a; + return 12; + } + }; + var a: S.A = undefined; + a.f = S.foo; + try expect(a.f(a) == 12); +} diff --git a/test/behavior/eval.zig b/test/behavior/eval.zig index d30c911678..ecc10859cd 100644 --- a/test/behavior/eval.zig +++ b/test/behavior/eval.zig @@ -217,3 +217,154 @@ const vertices = [_]Vertex{ .b = 1.0, }, }; + +test "statically initialized list" { + try expect(static_point_list[0].x == 1); + try expect(static_point_list[0].y == 2); + try expect(static_point_list[1].x == 3); + try expect(static_point_list[1].y == 4); +} +const Point = struct { + x: i32, + y: i32, +}; +const static_point_list = [_]Point{ + makePoint(1, 2), + makePoint(3, 4), +}; +fn makePoint(x: i32, y: i32) Point { + return Point{ + .x = x, + .y = y, + }; +} + +test "statically initialized array literal" { + const y: [4]u8 = st_init_arr_lit_x; + try expect(y[3] == 4); +} +const st_init_arr_lit_x = [_]u8{ 1, 2, 3, 4 }; + +const CmdFn = struct { + name: []const u8, + func: fn (i32) i32, +}; + +const cmd_fns = [_]CmdFn{ + CmdFn{ + .name = "one", + .func = one, + }, + CmdFn{ + .name = "two", + .func = two, + }, + CmdFn{ + .name = "three", + .func = three, + }, +}; +fn one(value: i32) i32 { + return value + 1; +} +fn two(value: i32) i32 { + return value + 2; +} +fn three(value: i32) i32 { + return value + 3; +} + +fn performFn(comptime prefix_char: u8, start_value: i32) i32 { + var result: i32 = start_value; + comptime var i = 0; + inline while (i < cmd_fns.len) : (i += 1) { + if (cmd_fns[i].name[0] == prefix_char) { + result = cmd_fns[i].func(result); + } + } + return result; +} + +test "comptime iterate over fn ptr list" { + try expect(performFn('t', 1) == 6); + try expect(performFn('o', 0) == 1); + try expect(performFn('w', 99) == 99); +} + +test "create global array with for loop" { + try expect(global_array[5] == 5 * 5); + try expect(global_array[9] == 9 * 9); +} + +const global_array = x: { + var result: [10]usize = undefined; + for (result) |*item, index| { + item.* = index * index; + } + break :x result; +}; + +fn generateTable(comptime T: type) [1010]T { + var res: [1010]T = undefined; + var i: usize = 0; + while (i < 1010) : (i += 1) { + res[i] = @intCast(T, i); + } + return res; +} + +fn doesAlotT(comptime T: type, value: usize) T { + @setEvalBranchQuota(5000); + const table = comptime blk: { + break :blk generateTable(T); + }; + return table[value]; +} + +test "@setEvalBranchQuota at same scope as generic function call" { + try expect(doesAlotT(u32, 2) == 2); +} + +pub const Info = struct { + version: u8, +}; + +pub const diamond_info = Info{ .version = 0 }; + +test "comptime modification of const struct field" { + comptime { + var res = diamond_info; + res.version = 1; + try expect(diamond_info.version == 0); + try expect(res.version == 1); + } +} + +test "refer to the type of a generic function" { + const Func = fn (type) void; + const f: Func = doNothingWithType; + f(i32); +} + +fn doNothingWithType(comptime T: type) void { + _ = T; +} + +test "zero extend from u0 to u1" { + var zero_u0: u0 = 0; + var zero_u1: u1 = zero_u0; + try expect(zero_u1 == 0); +} + +test "return 0 from function that has u0 return type" { + const S = struct { + fn foo_zero() u0 { + return 0; + } + }; + comptime { + if (S.foo_zero() != 0) { + @compileError("test failed"); + } + } +} diff --git a/test/behavior/eval_stage1.zig b/test/behavior/eval_stage1.zig index 6440558abc..c19c58455b 100644 --- a/test/behavior/eval_stage1.zig +++ b/test/behavior/eval_stage1.zig @@ -2,27 +2,6 @@ const std = @import("std"); const expect = std.testing.expect; const expectEqual = std.testing.expectEqual; -test "statically initialized list" { - try expect(static_point_list[0].x == 1); - try expect(static_point_list[0].y == 2); - try expect(static_point_list[1].x == 3); - try expect(static_point_list[1].y == 4); -} -const Point = struct { - x: i32, - y: i32, -}; -const static_point_list = [_]Point{ - makePoint(1, 2), - makePoint(3, 4), -}; -fn makePoint(x: i32, y: i32) Point { - return Point{ - .x = x, - .y = y, - }; -} - test "static eval list init" { try expect(static_vec3.data[2] == 1.0); try expect(vec3(0.0, 0.0, 3.0).data[2] == 3.0); @@ -54,27 +33,6 @@ var st_init_str_foo = StInitStrFoo{ .y = true, }; -test "statically initialized array literal" { - const y: [4]u8 = st_init_arr_lit_x; - try expect(y[3] == 4); -} -const st_init_arr_lit_x = [_]u8{ - 1, - 2, - 3, - 4, -}; - -test "const slice" { - comptime { - const a = "1234567890"; - try expect(a.len == 10); - const b = a[1..2]; - try expect(b.len == 1); - try expect(b[0] == '2'); - } -} - test "inlined loop has array literal with elided runtime scope on first iteration but not second iteration" { var runtime = [1]i32{3}; comptime var i: usize = 0; @@ -87,52 +45,6 @@ test "inlined loop has array literal with elided runtime scope on first iteratio } } -const CmdFn = struct { - name: []const u8, - func: fn (i32) i32, -}; - -const cmd_fns = [_]CmdFn{ - CmdFn{ - .name = "one", - .func = one, - }, - CmdFn{ - .name = "two", - .func = two, - }, - CmdFn{ - .name = "three", - .func = three, - }, -}; -fn one(value: i32) i32 { - return value + 1; -} -fn two(value: i32) i32 { - return value + 2; -} -fn three(value: i32) i32 { - return value + 3; -} - -fn performFn(comptime prefix_char: u8, start_value: i32) i32 { - var result: i32 = start_value; - comptime var i = 0; - inline while (i < cmd_fns.len) : (i += 1) { - if (cmd_fns[i].name[0] == prefix_char) { - result = cmd_fns[i].func(result); - } - } - return result; -} - -test "comptime iterate over fn ptr list" { - try expect(performFn('t', 1) == 6); - try expect(performFn('o', 0) == 1); - try expect(performFn('w', 99) == 99); -} - test "eval @setFloatMode at compile-time" { const result = comptime fnWithFloatMode(); try expect(result == 1234.0); @@ -204,19 +116,6 @@ const Foo = struct { var foo_contents = Foo{ .name = "a" }; const foo_ref = &foo_contents; -test "create global array with for loop" { - try expect(global_array[5] == 5 * 5); - try expect(global_array[9] == 9 * 9); -} - -const global_array = x: { - var result: [10]usize = undefined; - for (result) |*item, index| { - item.* = index * index; - } - break :x result; -}; - const hi1 = "hi"; const hi2 = hi1; test "const global shares pointer with other same one" { @@ -262,13 +161,6 @@ test "string literal used as comptime slice is memoized" { comptime try expect(TypeWithCompTimeSlice("link").Node == TypeWithCompTimeSlice("link").Node); } -test "comptime slice of undefined pointer of length 0" { - const slice1 = @as([*]i32, undefined)[0..0]; - try expect(slice1.len == 0); - const slice2 = @as([*]i32, undefined)[100..100]; - try expect(slice2.len == 0); -} - fn copyWithPartialInline(s: []u32, b: []u8) void { comptime var i: usize = 0; inline while (i < 4) : (i += 1) { @@ -308,44 +200,6 @@ fn increment(value: *i32) void { value.* += 1; } -fn generateTable(comptime T: type) [1010]T { - var res: [1010]T = undefined; - var i: usize = 0; - while (i < 1010) : (i += 1) { - res[i] = @intCast(T, i); - } - return res; -} - -fn doesAlotT(comptime T: type, value: usize) T { - @setEvalBranchQuota(5000); - const table = comptime blk: { - break :blk generateTable(T); - }; - return table[value]; -} - -test "@setEvalBranchQuota at same scope as generic function call" { - try expect(doesAlotT(u32, 2) == 2); -} - -test "comptime slice of slice preserves comptime var" { - comptime { - var buff: [10]u8 = undefined; - buff[0..][0..][0] = 1; - try expect(buff[0..][0..][0] == 1); - } -} - -test "comptime slice of pointer preserves comptime var" { - comptime { - var buff: [10]u8 = undefined; - var a = @ptrCast([*]u8, &buff); - a[0..1][0] = 1; - try expect(buff[0..][0..][0] == 1); - } -} - const SingleFieldStruct = struct { x: i32, @@ -362,15 +216,6 @@ test "const ptr to comptime mutable data is not memoized" { } } -test "array concat of slices gives slice" { - comptime { - var a: []const u8 = "aoeu"; - var b: []const u8 = "asdf"; - const c = a ++ b; - try expect(std.mem.eql(u8, c, "aoeuasdf")); - } -} - test "comptime shlWithOverflow" { const ct_shifted: u64 = comptime amt: { var amt = @as(u64, 0); @@ -401,43 +246,6 @@ test "runtime 128 bit integer division" { try expect(c == 15231399999); } -pub const Info = struct { - version: u8, -}; - -pub const diamond_info = Info{ .version = 0 }; - -test "comptime modification of const struct field" { - comptime { - var res = diamond_info; - res.version = 1; - try expect(diamond_info.version == 0); - try expect(res.version == 1); - } -} - -test "slice of type" { - comptime { - var types_array = [_]type{ i32, f64, type }; - for (types_array) |T, i| { - switch (i) { - 0 => try expect(T == i32), - 1 => try expect(T == f64), - 2 => try expect(T == type), - else => unreachable, - } - } - for (types_array[0..]) |T, i| { - switch (i) { - 0 => try expect(T == i32), - 1 => try expect(T == f64), - 2 => try expect(T == type), - else => unreachable, - } - } - } -} - const Wrapper = struct { T: type, }; @@ -502,55 +310,12 @@ test "inline for with same type but different values" { try expect(res == 5); } -test "refer to the type of a generic function" { - const Func = fn (type) void; - const f: Func = doNothingWithType; - f(i32); -} - -fn doNothingWithType(comptime T: type) void { - _ = T; -} - -test "zero extend from u0 to u1" { - var zero_u0: u0 = 0; - var zero_u1: u1 = zero_u0; - try expect(zero_u1 == 0); -} - test "bit shift a u1" { var x: u1 = 1; var y = x << 0; try expect(y == 1); } -test "comptime pointer cast array and then slice" { - const array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 }; - - const ptrA: [*]const u8 = @ptrCast([*]const u8, &array); - const sliceA: []const u8 = ptrA[0..2]; - - const ptrB: [*]const u8 = &array; - const sliceB: []const u8 = ptrB[0..2]; - - try expect(sliceA[1] == 2); - try expect(sliceB[1] == 2); -} - -test "slice bounds in comptime concatenation" { - const bs = comptime blk: { - const b = "........1........"; - break :blk b[8..9]; - }; - const str = "" ++ bs; - try expect(str.len == 1); - try expect(std.mem.eql(u8, str, "1")); - - const str2 = bs ++ ""; - try expect(str2.len == 1); - try expect(std.mem.eql(u8, str2, "1")); -} - test "comptime bitwise operators" { comptime { try expect(3 & 1 == 1); @@ -602,19 +367,6 @@ test "comptime assign int to optional int" { } } -test "return 0 from function that has u0 return type" { - const S = struct { - fn foo_zero() u0 { - return 0; - } - }; - comptime { - if (S.foo_zero() != 0) { - @compileError("test failed"); - } - } -} - test "two comptime calls with array default initialized to undefined" { const S = struct { const CrossTarget = struct { diff --git a/test/behavior/misc.zig b/test/behavior/misc.zig index 1b8f6ef4a2..83414f49b2 100644 --- a/test/behavior/misc.zig +++ b/test/behavior/misc.zig @@ -7,13 +7,6 @@ const builtin = @import("builtin"); fn emptyFn() void {} -test "constant equal function pointers" { - const alias = emptyFn; - try expect(comptime x: { - break :x emptyFn == alias; - }); -} - const addr1 = @ptrCast(*const u8, emptyFn); test "comptime cast fn to ptr" { const addr2 = @ptrCast(*const u8, emptyFn); @@ -35,17 +28,7 @@ test "string escapes" { try expectEqualStrings("\u{1234}\u{069}\u{1}", "\xe1\x88\xb4\x69\x01"); } -test "multiline string literal is null terminated" { - const s1 = - \\one - \\two) - \\three - ; - const s2 = "one\ntwo)\nthree"; - try expect(std.cstr.cmp(s1, s2) == 0); -} - -test "explicit cast maybe pointers" { +test "explicit cast optional pointers" { const a: ?*i32 = undefined; const b: ?*f32 = @ptrCast(?*f32, a); _ = b; @@ -159,22 +142,6 @@ export fn testPackedStuff(a: *const PackedStruct, b: *const PackedUnion) void { } } -test "self reference through fn ptr field" { - const S = struct { - const A = struct { - f: fn (A) u8, - }; - - fn foo(a: A) u8 { - _ = a; - return 12; - } - }; - var a: S.A = undefined; - a.f = S.foo; - try expect(a.f(a) == 12); -} - test "thread local variable" { const S = struct { threadlocal var t: i32 = 1234; @@ -183,19 +150,6 @@ test "thread local variable" { try expect(S.t == 1235); } -test "nested optional field in struct" { - const S2 = struct { - y: u8, - }; - const S1 = struct { - x: ?S2, - }; - var s = S1{ - .x = S2{ .y = 127 }, - }; - try expect(s.x.?.y == 127); -} - fn maybe(x: bool) anyerror!?u32 { return switch (x) { true => @as(u32, 42), diff --git a/test/behavior/optional.zig b/test/behavior/optional.zig index e2bf15627f..974dbf33c9 100644 --- a/test/behavior/optional.zig +++ b/test/behavior/optional.zig @@ -2,3 +2,37 @@ const std = @import("std"); const testing = std.testing; const expect = testing.expect; const expectEqual = testing.expectEqual; + +test "passing an optional integer as a parameter" { + const S = struct { + fn entry() bool { + var x: i32 = 1234; + return foo(x); + } + + fn foo(x: ?i32) bool { + return x.? == 1234; + } + }; + try expect(S.entry()); + comptime try expect(S.entry()); +} + +test "self-referential struct through a slice of optional" { + const S = struct { + const Node = struct { + children: []?Node, + data: ?u8, + + fn new() Node { + return Node{ + .children = undefined, + .data = null, + }; + } + }; + }; + + var n = S.Node.new(); + try expect(n.data == null); +} diff --git a/test/behavior/optional_stage1.zig b/test/behavior/optional_stage1.zig index 9448f501f4..4d3610f662 100644 --- a/test/behavior/optional_stage1.zig +++ b/test/behavior/optional_stage1.zig @@ -83,21 +83,6 @@ fn test_cmp_optional_non_optional() !void { }; } -test "passing an optional integer as a parameter" { - const S = struct { - fn entry() bool { - var x: i32 = 1234; - return foo(x); - } - - fn foo(x: ?i32) bool { - return x.? == 1234; - } - }; - try expect(S.entry()); - comptime try expect(S.entry()); -} - test "unwrap function call with optional pointer return value" { const S = struct { fn entry() !void { @@ -139,25 +124,6 @@ test "nested orelse" { comptime try S.entry(); } -test "self-referential struct through a slice of optional" { - const S = struct { - const Node = struct { - children: []?Node, - data: ?u8, - - fn new() Node { - return Node{ - .children = undefined, - .data = null, - }; - } - }; - }; - - var n = S.Node.new(); - try expect(n.data == null); -} - test "assigning to an unwrapped optional field in an inline loop" { comptime var maybe_pos_arg: ?comptime_int = null; inline for ("ab") |x| { diff --git a/test/behavior/slice_stage1.zig b/test/behavior/slice_stage1.zig index dbc59823ec..ab45d14543 100644 --- a/test/behavior/slice_stage1.zig +++ b/test/behavior/slice_stage1.zig @@ -20,6 +20,23 @@ test "slicing" { if (slice_rest.len != 10) unreachable; } +test "const slice" { + comptime { + const a = "1234567890"; + try expect(a.len == 10); + const b = a[1..2]; + try expect(b.len == 1); + try expect(b[0] == '2'); + } +} + +test "comptime slice of undefined pointer of length 0" { + const slice1 = @as([*]i32, undefined)[0..0]; + try expect(slice1.len == 0); + const slice2 = @as([*]i32, undefined)[100..100]; + try expect(slice2.len == 0); +} + test "slicing zero length array" { const s1 = ""[0..]; const s2 = ([_]u32{})[0..]; @@ -389,3 +406,78 @@ test "type coercion of pointer to anon struct literal to pointer to slice" { // try S.doTheTest(); comptime try S.doTheTest(); } + +test "comptime slice of slice preserves comptime var" { + comptime { + var buff: [10]u8 = undefined; + buff[0..][0..][0] = 1; + try expect(buff[0..][0..][0] == 1); + } +} + +test "comptime slice of pointer preserves comptime var" { + comptime { + var buff: [10]u8 = undefined; + var a = @ptrCast([*]u8, &buff); + a[0..1][0] = 1; + try expect(buff[0..][0..][0] == 1); + } +} + +test "array concat of slices gives slice" { + comptime { + var a: []const u8 = "aoeu"; + var b: []const u8 = "asdf"; + const c = a ++ b; + try expect(std.mem.eql(u8, c, "aoeuasdf")); + } +} + +test "slice of type" { + comptime { + var types_array = [_]type{ i32, f64, type }; + for (types_array) |T, i| { + switch (i) { + 0 => try expect(T == i32), + 1 => try expect(T == f64), + 2 => try expect(T == type), + else => unreachable, + } + } + for (types_array[0..]) |T, i| { + switch (i) { + 0 => try expect(T == i32), + 1 => try expect(T == f64), + 2 => try expect(T == type), + else => unreachable, + } + } + } +} + +test "comptime pointer cast array and then slice" { + const array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 }; + + const ptrA: [*]const u8 = @ptrCast([*]const u8, &array); + const sliceA: []const u8 = ptrA[0..2]; + + const ptrB: [*]const u8 = &array; + const sliceB: []const u8 = ptrB[0..2]; + + try expect(sliceA[1] == 2); + try expect(sliceB[1] == 2); +} + +test "slice bounds in comptime concatenation" { + const bs = comptime blk: { + const b = "........1........"; + break :blk b[8..9]; + }; + const str = "" ++ bs; + try expect(str.len == 1); + try expect(std.mem.eql(u8, str, "1")); + + const str2 = bs ++ ""; + try expect(str2.len == 1); + try expect(std.mem.eql(u8, str2, "1")); +} diff --git a/test/behavior/while.zig b/test/behavior/while.zig index a2f34d54c0..9e9ac5dc01 100644 --- a/test/behavior/while.zig +++ b/test/behavior/while.zig @@ -111,3 +111,91 @@ test "while copies its payload" { try S.doTheTest(); comptime try S.doTheTest(); } + +test "continue and break" { + try runContinueAndBreakTest(); + try expect(continue_and_break_counter == 8); +} +var continue_and_break_counter: i32 = 0; +fn runContinueAndBreakTest() !void { + var i: i32 = 0; + while (true) { + continue_and_break_counter += 2; + i += 1; + if (i < 4) { + continue; + } + break; + } + try expect(i == 4); +} + +test "while with optional as condition" { + numbers_left = 10; + var sum: i32 = 0; + while (getNumberOrNull()) |value| { + sum += value; + } + try expect(sum == 45); +} + +test "while with optional as condition with else" { + numbers_left = 10; + var sum: i32 = 0; + var got_else: i32 = 0; + while (getNumberOrNull()) |value| { + sum += value; + try expect(got_else == 0); + } else { + got_else += 1; + } + try expect(sum == 45); + try expect(got_else == 1); +} + +test "while on bool with else result follow else prong" { + const result = while (returnFalse()) { + break @as(i32, 10); + } else @as(i32, 2); + try expect(result == 2); +} + +test "while on bool with else result follow break prong" { + const result = while (returnTrue()) { + break @as(i32, 10); + } else @as(i32, 2); + try expect(result == 10); +} + +test "while on optional with else result follow else prong" { + const result = while (returnNull()) |value| { + break value; + } else @as(i32, 2); + try expect(result == 2); +} + +test "while on optional with else result follow break prong" { + const result = while (returnOptional(10)) |value| { + break value; + } else @as(i32, 2); + try expect(result == 10); +} + +fn returnNull() ?i32 { + return null; +} +fn returnOptional(x: i32) ?i32 { + return x; +} +fn returnError() anyerror!i32 { + return error.YouWantedAnError; +} +fn returnSuccess(x: i32) anyerror!i32 { + return x; +} +fn returnFalse() bool { + return false; +} +fn returnTrue() bool { + return true; +} diff --git a/test/behavior/while_stage1.zig b/test/behavior/while_stage1.zig index dc83d5d163..2ab19d66e1 100644 --- a/test/behavior/while_stage1.zig +++ b/test/behavior/while_stage1.zig @@ -1,24 +1,6 @@ const std = @import("std"); const expect = std.testing.expect; -test "continue and break" { - try runContinueAndBreakTest(); - try expect(continue_and_break_counter == 8); -} -var continue_and_break_counter: i32 = 0; -fn runContinueAndBreakTest() !void { - var i: i32 = 0; - while (true) { - continue_and_break_counter += 2; - i += 1; - if (i < 4) { - continue; - } - break; - } - try expect(i == 4); -} - test "return with implicit cast from while loop" { returnWithImplicitCastFromWhileLoopTest() catch unreachable; } @@ -28,29 +10,6 @@ fn returnWithImplicitCastFromWhileLoopTest() anyerror!void { } } -test "while with optional as condition" { - numbers_left = 10; - var sum: i32 = 0; - while (getNumberOrNull()) |value| { - sum += value; - } - try expect(sum == 45); -} - -test "while with optional as condition with else" { - numbers_left = 10; - var sum: i32 = 0; - var got_else: i32 = 0; - while (getNumberOrNull()) |value| { - sum += value; - try expect(got_else == 0); - } else { - got_else += 1; - } - try expect(sum == 45); - try expect(got_else == 1); -} - test "while with error union condition" { numbers_left = 10; var sum: i32 = 0; @@ -79,20 +38,6 @@ fn getNumberOrNull() ?i32 { }; } -test "while on optional with else result follow else prong" { - const result = while (returnNull()) |value| { - break value; - } else @as(i32, 2); - try expect(result == 2); -} - -test "while on optional with else result follow break prong" { - const result = while (returnOptional(10)) |value| { - break value; - } else @as(i32, 2); - try expect(result == 10); -} - test "while on error union with else result follow else prong" { const result = while (returnError()) |value| { break value; @@ -107,20 +52,6 @@ test "while on error union with else result follow break prong" { try expect(result == 10); } -test "while on bool with else result follow else prong" { - const result = while (returnFalse()) { - break @as(i32, 10); - } else @as(i32, 2); - try expect(result == 2); -} - -test "while on bool with else result follow break prong" { - const result = while (returnTrue()) { - break @as(i32, 10); - } else @as(i32, 2); - try expect(result == 10); -} - fn returnNull() ?i32 { return null; }