| author | |
| committer | |
| log | cacd5366a6707cb030e212ea3cc46052168d4006 |
| tree | 8e6d5d7c40bb763acd180040af8396d4198cbe92 |
| parent | 55eea3b045c86c78eb8d9cc862122d260352a631 |
and move over some passing tests11 files changed, 428 insertions(+), 402 deletions(-)
src/codegen/llvm.zig+26-3| ... | @@ -2341,10 +2341,33 @@ pub const FuncGen = struct { | ... | @@ -2341,10 +2341,33 @@ pub const FuncGen = struct { |
| 2341 | } | 2341 | } |
| 2342 | 2342 | ||
| 2343 | fn airWrapOptional(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 2343 | fn airWrapOptional(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { |
| 2344 | if (self.liveness.isUnused(inst)) | 2344 | if (self.liveness.isUnused(inst)) return null; |
| 2345 | return null; | ||
| 2346 | 2345 | ||
| 2347 | return self.todo("implement llvm codegen for 'airWrapOptional'", .{}); | 2346 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2347 | const operand_ty = self.air.typeOf(ty_op.operand); | ||
| 2348 | const non_null_bit = self.context.intType(1).constAllOnes(); | ||
| 2349 | if (!operand_ty.hasCodeGenBits()) return non_null_bit; | ||
| 2350 | const operand = try self.resolveInst(ty_op.operand); | ||
| 2351 | const optional_ty = self.air.typeOfIndex(inst); | ||
| 2352 | if (optional_ty.isPtrLikeOptional()) return operand; | ||
| 2353 | const llvm_optional_ty = try self.dg.llvmType(optional_ty); | ||
| 2354 | if (isByRef(optional_ty)) { | ||
| 2355 | const optional_ptr = self.buildAlloca(llvm_optional_ty); | ||
| 2356 | const payload_ptr = self.builder.buildStructGEP(optional_ptr, 0, ""); | ||
| 2357 | var buf: Type.Payload.ElemType = undefined; | ||
| 2358 | const payload_ty = operand_ty.optionalChild(&buf); | ||
| 2359 | var ptr_ty_payload: Type.Payload.ElemType = .{ | ||
| 2360 | .base = .{ .tag = .single_mut_pointer }, | ||
| 2361 | .data = payload_ty, | ||
| 2362 | }; | ||
| 2363 | const payload_ptr_ty = Type.initPayload(&ptr_ty_payload.base); | ||
| 2364 | self.store(payload_ptr, payload_ptr_ty, operand, .NotAtomic); | ||
| 2365 | const non_null_ptr = self.builder.buildStructGEP(optional_ptr, 1, ""); | ||
| 2366 | _ = self.builder.buildStore(non_null_bit, non_null_ptr); | ||
| 2367 | return optional_ptr; | ||
| 2368 | } | ||
| 2369 | const partial = self.builder.buildInsertValue(llvm_optional_ty.getUndef(), operand, 0, ""); | ||
| 2370 | return self.builder.buildInsertValue(partial, non_null_bit, 1, ""); | ||
| 2348 | } | 2371 | } |
| 2349 | 2372 | ||
| 2350 | fn airWrapErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 2373 | fn airWrapErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { |
test/behavior.zig+1-1| ... | @@ -28,6 +28,7 @@ test { | ... | @@ -28,6 +28,7 @@ test { |
| 28 | _ = @import("behavior/member_func.zig"); | 28 | _ = @import("behavior/member_func.zig"); |
| 29 | _ = @import("behavior/optional.zig"); | 29 | _ = @import("behavior/optional.zig"); |
| 30 | _ = @import("behavior/pointers.zig"); | 30 | _ = @import("behavior/pointers.zig"); |
| 31 | _ = @import("behavior/pub_enum.zig"); | ||
| 31 | _ = @import("behavior/slice.zig"); | 32 | _ = @import("behavior/slice.zig"); |
| 32 | _ = @import("behavior/sizeof_and_typeof.zig"); | 33 | _ = @import("behavior/sizeof_and_typeof.zig"); |
| 33 | _ = @import("behavior/struct.zig"); | 34 | _ = @import("behavior/struct.zig"); |
| ... | @@ -140,7 +141,6 @@ test { | ... | @@ -140,7 +141,6 @@ test { |
| 140 | _ = @import("behavior/pointers_stage1.zig"); | 141 | _ = @import("behavior/pointers_stage1.zig"); |
| 141 | _ = @import("behavior/popcount.zig"); | 142 | _ = @import("behavior/popcount.zig"); |
| 142 | _ = @import("behavior/ptrcast.zig"); | 143 | _ = @import("behavior/ptrcast.zig"); |
| 143 | _ = @import("behavior/pub_enum.zig"); | ||
| 144 | _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig"); | 144 | _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig"); |
| 145 | _ = @import("behavior/reflection.zig"); | 145 | _ = @import("behavior/reflection.zig"); |
| 146 | { | 146 | { |
test/behavior/basic.zig+35| ... | @@ -411,3 +411,38 @@ test "use of declaration with same name as primitive" { | ... | @@ -411,3 +411,38 @@ test "use of declaration with same name as primitive" { |
| 411 | const c: @"u8" = 300; | 411 | const c: @"u8" = 300; |
| 412 | try expect(c == 300); | 412 | try expect(c == 300); |
| 413 | } | 413 | } |
| 414 | |||
| 415 | fn emptyFn() void {} | ||
| 416 | |||
| 417 | test "constant equal function pointers" { | ||
| 418 | const alias = emptyFn; | ||
| 419 | try expect(comptime x: { | ||
| 420 | break :x emptyFn == alias; | ||
| 421 | }); | ||
| 422 | } | ||
| 423 | |||
| 424 | test "multiline string literal is null terminated" { | ||
| 425 | const s1 = | ||
| 426 | \\one | ||
| 427 | \\two) | ||
| 428 | \\three | ||
| 429 | ; | ||
| 430 | const s2 = "one\ntwo)\nthree"; | ||
| 431 | try expect(std.cstr.cmp(s1, s2) == 0); | ||
| 432 | } | ||
| 433 | |||
| 434 | test "self reference through fn ptr field" { | ||
| 435 | const S = struct { | ||
| 436 | const A = struct { | ||
| 437 | f: fn (A) u8, | ||
| 438 | }; | ||
| 439 | |||
| 440 | fn foo(a: A) u8 { | ||
| 441 | _ = a; | ||
| 442 | return 12; | ||
| 443 | } | ||
| 444 | }; | ||
| 445 | var a: S.A = undefined; | ||
| 446 | a.f = S.foo; | ||
| 447 | try expect(a.f(a) == 12); | ||
| 448 | } |
test/behavior/eval.zig+151| ... | @@ -217,3 +217,154 @@ const vertices = [_]Vertex{ | ... | @@ -217,3 +217,154 @@ const vertices = [_]Vertex{ |
| 217 | .b = 1.0, | 217 | .b = 1.0, |
| 218 | }, | 218 | }, |
| 219 | }; | 219 | }; |
| 220 | |||
| 221 | test "statically initialized list" { | ||
| 222 | try expect(static_point_list[0].x == 1); | ||
| 223 | try expect(static_point_list[0].y == 2); | ||
| 224 | try expect(static_point_list[1].x == 3); | ||
| 225 | try expect(static_point_list[1].y == 4); | ||
| 226 | } | ||
| 227 | const Point = struct { | ||
| 228 | x: i32, | ||
| 229 | y: i32, | ||
| 230 | }; | ||
| 231 | const static_point_list = [_]Point{ | ||
| 232 | makePoint(1, 2), | ||
| 233 | makePoint(3, 4), | ||
| 234 | }; | ||
| 235 | fn makePoint(x: i32, y: i32) Point { | ||
| 236 | return Point{ | ||
| 237 | .x = x, | ||
| 238 | .y = y, | ||
| 239 | }; | ||
| 240 | } | ||
| 241 | |||
| 242 | test "statically initialized array literal" { | ||
| 243 | const y: [4]u8 = st_init_arr_lit_x; | ||
| 244 | try expect(y[3] == 4); | ||
| 245 | } | ||
| 246 | const st_init_arr_lit_x = [_]u8{ 1, 2, 3, 4 }; | ||
| 247 | |||
| 248 | const CmdFn = struct { | ||
| 249 | name: []const u8, | ||
| 250 | func: fn (i32) i32, | ||
| 251 | }; | ||
| 252 | |||
| 253 | const cmd_fns = [_]CmdFn{ | ||
| 254 | CmdFn{ | ||
| 255 | .name = "one", | ||
| 256 | .func = one, | ||
| 257 | }, | ||
| 258 | CmdFn{ | ||
| 259 | .name = "two", | ||
| 260 | .func = two, | ||
| 261 | }, | ||
| 262 | CmdFn{ | ||
| 263 | .name = "three", | ||
| 264 | .func = three, | ||
| 265 | }, | ||
| 266 | }; | ||
| 267 | fn one(value: i32) i32 { | ||
| 268 | return value + 1; | ||
| 269 | } | ||
| 270 | fn two(value: i32) i32 { | ||
| 271 | return value + 2; | ||
| 272 | } | ||
| 273 | fn three(value: i32) i32 { | ||
| 274 | return value + 3; | ||
| 275 | } | ||
| 276 | |||
| 277 | fn performFn(comptime prefix_char: u8, start_value: i32) i32 { | ||
| 278 | var result: i32 = start_value; | ||
| 279 | comptime var i = 0; | ||
| 280 | inline while (i < cmd_fns.len) : (i += 1) { | ||
| 281 | if (cmd_fns[i].name[0] == prefix_char) { | ||
| 282 | result = cmd_fns[i].func(result); | ||
| 283 | } | ||
| 284 | } | ||
| 285 | return result; | ||
| 286 | } | ||
| 287 | |||
| 288 | test "comptime iterate over fn ptr list" { | ||
| 289 | try expect(performFn('t', 1) == 6); | ||
| 290 | try expect(performFn('o', 0) == 1); | ||
| 291 | try expect(performFn('w', 99) == 99); | ||
| 292 | } | ||
| 293 | |||
| 294 | test "create global array with for loop" { | ||
| 295 | try expect(global_array[5] == 5 * 5); | ||
| 296 | try expect(global_array[9] == 9 * 9); | ||
| 297 | } | ||
| 298 | |||
| 299 | const global_array = x: { | ||
| 300 | var result: [10]usize = undefined; | ||
| 301 | for (result) |*item, index| { | ||
| 302 | item.* = index * index; | ||
| 303 | } | ||
| 304 | break :x result; | ||
| 305 | }; | ||
| 306 | |||
| 307 | fn generateTable(comptime T: type) [1010]T { | ||
| 308 | var res: [1010]T = undefined; | ||
| 309 | var i: usize = 0; | ||
| 310 | while (i < 1010) : (i += 1) { | ||
| 311 | res[i] = @intCast(T, i); | ||
| 312 | } | ||
| 313 | return res; | ||
| 314 | } | ||
| 315 | |||
| 316 | fn doesAlotT(comptime T: type, value: usize) T { | ||
| 317 | @setEvalBranchQuota(5000); | ||
| 318 | const table = comptime blk: { | ||
| 319 | break :blk generateTable(T); | ||
| 320 | }; | ||
| 321 | return table[value]; | ||
| 322 | } | ||
| 323 | |||
| 324 | test "@setEvalBranchQuota at same scope as generic function call" { | ||
| 325 | try expect(doesAlotT(u32, 2) == 2); | ||
| 326 | } | ||
| 327 | |||
| 328 | pub const Info = struct { | ||
| 329 | version: u8, | ||
| 330 | }; | ||
| 331 | |||
| 332 | pub const diamond_info = Info{ .version = 0 }; | ||
| 333 | |||
| 334 | test "comptime modification of const struct field" { | ||
| 335 | comptime { | ||
| 336 | var res = diamond_info; | ||
| 337 | res.version = 1; | ||
| 338 | try expect(diamond_info.version == 0); | ||
| 339 | try expect(res.version == 1); | ||
| 340 | } | ||
| 341 | } | ||
| 342 | |||
| 343 | test "refer to the type of a generic function" { | ||
| 344 | const Func = fn (type) void; | ||
| 345 | const f: Func = doNothingWithType; | ||
| 346 | f(i32); | ||
| 347 | } | ||
| 348 | |||
| 349 | fn doNothingWithType(comptime T: type) void { | ||
| 350 | _ = T; | ||
| 351 | } | ||
| 352 | |||
| 353 | test "zero extend from u0 to u1" { | ||
| 354 | var zero_u0: u0 = 0; | ||
| 355 | var zero_u1: u1 = zero_u0; | ||
| 356 | try expect(zero_u1 == 0); | ||
| 357 | } | ||
| 358 | |||
| 359 | test "return 0 from function that has u0 return type" { | ||
| 360 | const S = struct { | ||
| 361 | fn foo_zero() u0 { | ||
| 362 | return 0; | ||
| 363 | } | ||
| 364 | }; | ||
| 365 | comptime { | ||
| 366 | if (S.foo_zero() != 0) { | ||
| 367 | @compileError("test failed"); | ||
| 368 | } | ||
| 369 | } | ||
| 370 | } |
test/behavior/eval_stage1.zig-248| ... | @@ -2,27 +2,6 @@ const std = @import("std"); | ... | @@ -2,27 +2,6 @@ const std = @import("std"); |
| 2 | const expect = std.testing.expect; | 2 | const expect = std.testing.expect; |
| 3 | const expectEqual = std.testing.expectEqual; | 3 | const expectEqual = std.testing.expectEqual; |
| 4 | 4 | ||
| 5 | test "statically initialized list" { | ||
| 6 | try expect(static_point_list[0].x == 1); | ||
| 7 | try expect(static_point_list[0].y == 2); | ||
| 8 | try expect(static_point_list[1].x == 3); | ||
| 9 | try expect(static_point_list[1].y == 4); | ||
| 10 | } | ||
| 11 | const Point = struct { | ||
| 12 | x: i32, | ||
| 13 | y: i32, | ||
| 14 | }; | ||
| 15 | const static_point_list = [_]Point{ | ||
| 16 | makePoint(1, 2), | ||
| 17 | makePoint(3, 4), | ||
| 18 | }; | ||
| 19 | fn makePoint(x: i32, y: i32) Point { | ||
| 20 | return Point{ | ||
| 21 | .x = x, | ||
| 22 | .y = y, | ||
| 23 | }; | ||
| 24 | } | ||
| 25 | |||
| 26 | test "static eval list init" { | 5 | test "static eval list init" { |
| 27 | try expect(static_vec3.data[2] == 1.0); | 6 | try expect(static_vec3.data[2] == 1.0); |
| 28 | try expect(vec3(0.0, 0.0, 3.0).data[2] == 3.0); | 7 | try expect(vec3(0.0, 0.0, 3.0).data[2] == 3.0); |
| ... | @@ -54,27 +33,6 @@ var st_init_str_foo = StInitStrFoo{ | ... | @@ -54,27 +33,6 @@ var st_init_str_foo = StInitStrFoo{ |
| 54 | .y = true, | 33 | .y = true, |
| 55 | }; | 34 | }; |
| 56 | 35 | ||
| 57 | test "statically initialized array literal" { | ||
| 58 | const y: [4]u8 = st_init_arr_lit_x; | ||
| 59 | try expect(y[3] == 4); | ||
| 60 | } | ||
| 61 | const st_init_arr_lit_x = [_]u8{ | ||
| 62 | 1, | ||
| 63 | 2, | ||
| 64 | 3, | ||
| 65 | 4, | ||
| 66 | }; | ||
| 67 | |||
| 68 | test "const slice" { | ||
| 69 | comptime { | ||
| 70 | const a = "1234567890"; | ||
| 71 | try expect(a.len == 10); | ||
| 72 | const b = a[1..2]; | ||
| 73 | try expect(b.len == 1); | ||
| 74 | try expect(b[0] == '2'); | ||
| 75 | } | ||
| 76 | } | ||
| 77 | |||
| 78 | test "inlined loop has array literal with elided runtime scope on first iteration but not second iteration" { | 36 | test "inlined loop has array literal with elided runtime scope on first iteration but not second iteration" { |
| 79 | var runtime = [1]i32{3}; | 37 | var runtime = [1]i32{3}; |
| 80 | comptime var i: usize = 0; | 38 | comptime var i: usize = 0; |
| ... | @@ -87,52 +45,6 @@ test "inlined loop has array literal with elided runtime scope on first iteratio | ... | @@ -87,52 +45,6 @@ test "inlined loop has array literal with elided runtime scope on first iteratio |
| 87 | } | 45 | } |
| 88 | } | 46 | } |
| 89 | 47 | ||
| 90 | const CmdFn = struct { | ||
| 91 | name: []const u8, | ||
| 92 | func: fn (i32) i32, | ||
| 93 | }; | ||
| 94 | |||
| 95 | const cmd_fns = [_]CmdFn{ | ||
| 96 | CmdFn{ | ||
| 97 | .name = "one", | ||
| 98 | .func = one, | ||
| 99 | }, | ||
| 100 | CmdFn{ | ||
| 101 | .name = "two", | ||
| 102 | .func = two, | ||
| 103 | }, | ||
| 104 | CmdFn{ | ||
| 105 | .name = "three", | ||
| 106 | .func = three, | ||
| 107 | }, | ||
| 108 | }; | ||
| 109 | fn one(value: i32) i32 { | ||
| 110 | return value + 1; | ||
| 111 | } | ||
| 112 | fn two(value: i32) i32 { | ||
| 113 | return value + 2; | ||
| 114 | } | ||
| 115 | fn three(value: i32) i32 { | ||
| 116 | return value + 3; | ||
| 117 | } | ||
| 118 | |||
| 119 | fn performFn(comptime prefix_char: u8, start_value: i32) i32 { | ||
| 120 | var result: i32 = start_value; | ||
| 121 | comptime var i = 0; | ||
| 122 | inline while (i < cmd_fns.len) : (i += 1) { | ||
| 123 | if (cmd_fns[i].name[0] == prefix_char) { | ||
| 124 | result = cmd_fns[i].func(result); | ||
| 125 | } | ||
| 126 | } | ||
| 127 | return result; | ||
| 128 | } | ||
| 129 | |||
| 130 | test "comptime iterate over fn ptr list" { | ||
| 131 | try expect(performFn('t', 1) == 6); | ||
| 132 | try expect(performFn('o', 0) == 1); | ||
| 133 | try expect(performFn('w', 99) == 99); | ||
| 134 | } | ||
| 135 | |||
| 136 | test "eval @setFloatMode at compile-time" { | 48 | test "eval @setFloatMode at compile-time" { |
| 137 | const result = comptime fnWithFloatMode(); | 49 | const result = comptime fnWithFloatMode(); |
| 138 | try expect(result == 1234.0); | 50 | try expect(result == 1234.0); |
| ... | @@ -204,19 +116,6 @@ const Foo = struct { | ... | @@ -204,19 +116,6 @@ const Foo = struct { |
| 204 | var foo_contents = Foo{ .name = "a" }; | 116 | var foo_contents = Foo{ .name = "a" }; |
| 205 | const foo_ref = &foo_contents; | 117 | const foo_ref = &foo_contents; |
| 206 | 118 | ||
| 207 | test "create global array with for loop" { | ||
| 208 | try expect(global_array[5] == 5 * 5); | ||
| 209 | try expect(global_array[9] == 9 * 9); | ||
| 210 | } | ||
| 211 | |||
| 212 | const global_array = x: { | ||
| 213 | var result: [10]usize = undefined; | ||
| 214 | for (result) |*item, index| { | ||
| 215 | item.* = index * index; | ||
| 216 | } | ||
| 217 | break :x result; | ||
| 218 | }; | ||
| 219 | |||
| 220 | const hi1 = "hi"; | 119 | const hi1 = "hi"; |
| 221 | const hi2 = hi1; | 120 | const hi2 = hi1; |
| 222 | test "const global shares pointer with other same one" { | 121 | test "const global shares pointer with other same one" { |
| ... | @@ -262,13 +161,6 @@ test "string literal used as comptime slice is memoized" { | ... | @@ -262,13 +161,6 @@ test "string literal used as comptime slice is memoized" { |
| 262 | comptime try expect(TypeWithCompTimeSlice("link").Node == TypeWithCompTimeSlice("link").Node); | 161 | comptime try expect(TypeWithCompTimeSlice("link").Node == TypeWithCompTimeSlice("link").Node); |
| 263 | } | 162 | } |
| 264 | 163 | ||
| 265 | test "comptime slice of undefined pointer of length 0" { | ||
| 266 | const slice1 = @as([*]i32, undefined)[0..0]; | ||
| 267 | try expect(slice1.len == 0); | ||
| 268 | const slice2 = @as([*]i32, undefined)[100..100]; | ||
| 269 | try expect(slice2.len == 0); | ||
| 270 | } | ||
| 271 | |||
| 272 | fn copyWithPartialInline(s: []u32, b: []u8) void { | 164 | fn copyWithPartialInline(s: []u32, b: []u8) void { |
| 273 | comptime var i: usize = 0; | 165 | comptime var i: usize = 0; |
| 274 | inline while (i < 4) : (i += 1) { | 166 | inline while (i < 4) : (i += 1) { |
| ... | @@ -308,44 +200,6 @@ fn increment(value: *i32) void { | ... | @@ -308,44 +200,6 @@ fn increment(value: *i32) void { |
| 308 | value.* += 1; | 200 | value.* += 1; |
| 309 | } | 201 | } |
| 310 | 202 | ||
| 311 | fn generateTable(comptime T: type) [1010]T { | ||
| 312 | var res: [1010]T = undefined; | ||
| 313 | var i: usize = 0; | ||
| 314 | while (i < 1010) : (i += 1) { | ||
| 315 | res[i] = @intCast(T, i); | ||
| 316 | } | ||
| 317 | return res; | ||
| 318 | } | ||
| 319 | |||
| 320 | fn doesAlotT(comptime T: type, value: usize) T { | ||
| 321 | @setEvalBranchQuota(5000); | ||
| 322 | const table = comptime blk: { | ||
| 323 | break :blk generateTable(T); | ||
| 324 | }; | ||
| 325 | return table[value]; | ||
| 326 | } | ||
| 327 | |||
| 328 | test "@setEvalBranchQuota at same scope as generic function call" { | ||
| 329 | try expect(doesAlotT(u32, 2) == 2); | ||
| 330 | } | ||
| 331 | |||
| 332 | test "comptime slice of slice preserves comptime var" { | ||
| 333 | comptime { | ||
| 334 | var buff: [10]u8 = undefined; | ||
| 335 | buff[0..][0..][0] = 1; | ||
| 336 | try expect(buff[0..][0..][0] == 1); | ||
| 337 | } | ||
| 338 | } | ||
| 339 | |||
| 340 | test "comptime slice of pointer preserves comptime var" { | ||
| 341 | comptime { | ||
| 342 | var buff: [10]u8 = undefined; | ||
| 343 | var a = @ptrCast([*]u8, &buff); | ||
| 344 | a[0..1][0] = 1; | ||
| 345 | try expect(buff[0..][0..][0] == 1); | ||
| 346 | } | ||
| 347 | } | ||
| 348 | |||
| 349 | const SingleFieldStruct = struct { | 203 | const SingleFieldStruct = struct { |
| 350 | x: i32, | 204 | x: i32, |
| 351 | 205 | ||
| ... | @@ -362,15 +216,6 @@ test "const ptr to comptime mutable data is not memoized" { | ... | @@ -362,15 +216,6 @@ test "const ptr to comptime mutable data is not memoized" { |
| 362 | } | 216 | } |
| 363 | } | 217 | } |
| 364 | 218 | ||
| 365 | test "array concat of slices gives slice" { | ||
| 366 | comptime { | ||
| 367 | var a: []const u8 = "aoeu"; | ||
| 368 | var b: []const u8 = "asdf"; | ||
| 369 | const c = a ++ b; | ||
| 370 | try expect(std.mem.eql(u8, c, "aoeuasdf")); | ||
| 371 | } | ||
| 372 | } | ||
| 373 | |||
| 374 | test "comptime shlWithOverflow" { | 219 | test "comptime shlWithOverflow" { |
| 375 | const ct_shifted: u64 = comptime amt: { | 220 | const ct_shifted: u64 = comptime amt: { |
| 376 | var amt = @as(u64, 0); | 221 | var amt = @as(u64, 0); |
| ... | @@ -401,43 +246,6 @@ test "runtime 128 bit integer division" { | ... | @@ -401,43 +246,6 @@ test "runtime 128 bit integer division" { |
| 401 | try expect(c == 15231399999); | 246 | try expect(c == 15231399999); |
| 402 | } | 247 | } |
| 403 | 248 | ||
| 404 | pub const Info = struct { | ||
| 405 | version: u8, | ||
| 406 | }; | ||
| 407 | |||
| 408 | pub const diamond_info = Info{ .version = 0 }; | ||
| 409 | |||
| 410 | test "comptime modification of const struct field" { | ||
| 411 | comptime { | ||
| 412 | var res = diamond_info; | ||
| 413 | res.version = 1; | ||
| 414 | try expect(diamond_info.version == 0); | ||
| 415 | try expect(res.version == 1); | ||
| 416 | } | ||
| 417 | } | ||
| 418 | |||
| 419 | test "slice of type" { | ||
| 420 | comptime { | ||
| 421 | var types_array = [_]type{ i32, f64, type }; | ||
| 422 | for (types_array) |T, i| { | ||
| 423 | switch (i) { | ||
| 424 | 0 => try expect(T == i32), | ||
| 425 | 1 => try expect(T == f64), | ||
| 426 | 2 => try expect(T == type), | ||
| 427 | else => unreachable, | ||
| 428 | } | ||
| 429 | } | ||
| 430 | for (types_array[0..]) |T, i| { | ||
| 431 | switch (i) { | ||
| 432 | 0 => try expect(T == i32), | ||
| 433 | 1 => try expect(T == f64), | ||
| 434 | 2 => try expect(T == type), | ||
| 435 | else => unreachable, | ||
| 436 | } | ||
| 437 | } | ||
| 438 | } | ||
| 439 | } | ||
| 440 | |||
| 441 | const Wrapper = struct { | 249 | const Wrapper = struct { |
| 442 | T: type, | 250 | T: type, |
| 443 | }; | 251 | }; |
| ... | @@ -502,55 +310,12 @@ test "inline for with same type but different values" { | ... | @@ -502,55 +310,12 @@ test "inline for with same type but different values" { |
| 502 | try expect(res == 5); | 310 | try expect(res == 5); |
| 503 | } | 311 | } |
| 504 | 312 | ||
| 505 | test "refer to the type of a generic function" { | ||
| 506 | const Func = fn (type) void; | ||
| 507 | const f: Func = doNothingWithType; | ||
| 508 | f(i32); | ||
| 509 | } | ||
| 510 | |||
| 511 | fn doNothingWithType(comptime T: type) void { | ||
| 512 | _ = T; | ||
| 513 | } | ||
| 514 | |||
| 515 | test "zero extend from u0 to u1" { | ||
| 516 | var zero_u0: u0 = 0; | ||
| 517 | var zero_u1: u1 = zero_u0; | ||
| 518 | try expect(zero_u1 == 0); | ||
| 519 | } | ||
| 520 | |||
| 521 | test "bit shift a u1" { | 313 | test "bit shift a u1" { |
| 522 | var x: u1 = 1; | 314 | var x: u1 = 1; |
| 523 | var y = x << 0; | 315 | var y = x << 0; |
| 524 | try expect(y == 1); | 316 | try expect(y == 1); |
| 525 | } | 317 | } |
| 526 | 318 | ||
| 527 | test "comptime pointer cast array and then slice" { | ||
| 528 | const array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 }; | ||
| 529 | |||
| 530 | const ptrA: [*]const u8 = @ptrCast([*]const u8, &array); | ||
| 531 | const sliceA: []const u8 = ptrA[0..2]; | ||
| 532 | |||
| 533 | const ptrB: [*]const u8 = &array; | ||
| 534 | const sliceB: []const u8 = ptrB[0..2]; | ||
| 535 | |||
| 536 | try expect(sliceA[1] == 2); | ||
| 537 | try expect(sliceB[1] == 2); | ||
| 538 | } | ||
| 539 | |||
| 540 | test "slice bounds in comptime concatenation" { | ||
| 541 | const bs = comptime blk: { | ||
| 542 | const b = "........1........"; | ||
| 543 | break :blk b[8..9]; | ||
| 544 | }; | ||
| 545 | const str = "" ++ bs; | ||
| 546 | try expect(str.len == 1); | ||
| 547 | try expect(std.mem.eql(u8, str, "1")); | ||
| 548 | |||
| 549 | const str2 = bs ++ ""; | ||
| 550 | try expect(str2.len == 1); | ||
| 551 | try expect(std.mem.eql(u8, str2, "1")); | ||
| 552 | } | ||
| 553 | |||
| 554 | test "comptime bitwise operators" { | 319 | test "comptime bitwise operators" { |
| 555 | comptime { | 320 | comptime { |
| 556 | try expect(3 & 1 == 1); | 321 | try expect(3 & 1 == 1); |
| ... | @@ -602,19 +367,6 @@ test "comptime assign int to optional int" { | ... | @@ -602,19 +367,6 @@ test "comptime assign int to optional int" { |
| 602 | } | 367 | } |
| 603 | } | 368 | } |
| 604 | 369 | ||
| 605 | test "return 0 from function that has u0 return type" { | ||
| 606 | const S = struct { | ||
| 607 | fn foo_zero() u0 { | ||
| 608 | return 0; | ||
| 609 | } | ||
| 610 | }; | ||
| 611 | comptime { | ||
| 612 | if (S.foo_zero() != 0) { | ||
| 613 | @compileError("test failed"); | ||
| 614 | } | ||
| 615 | } | ||
| 616 | } | ||
| 617 | |||
| 618 | test "two comptime calls with array default initialized to undefined" { | 370 | test "two comptime calls with array default initialized to undefined" { |
| 619 | const S = struct { | 371 | const S = struct { |
| 620 | const CrossTarget = struct { | 372 | const CrossTarget = struct { |
test/behavior/misc.zig+1-47| ... | @@ -7,13 +7,6 @@ const builtin = @import("builtin"); | ... | @@ -7,13 +7,6 @@ const builtin = @import("builtin"); |
| 7 | 7 | ||
| 8 | fn emptyFn() void {} | 8 | fn emptyFn() void {} |
| 9 | 9 | ||
| 10 | test "constant equal function pointers" { | ||
| 11 | const alias = emptyFn; | ||
| 12 | try expect(comptime x: { | ||
| 13 | break :x emptyFn == alias; | ||
| 14 | }); | ||
| 15 | } | ||
| 16 | |||
| 17 | const addr1 = @ptrCast(*const u8, emptyFn); | 10 | const addr1 = @ptrCast(*const u8, emptyFn); |
| 18 | test "comptime cast fn to ptr" { | 11 | test "comptime cast fn to ptr" { |
| 19 | const addr2 = @ptrCast(*const u8, emptyFn); | 12 | const addr2 = @ptrCast(*const u8, emptyFn); |
| ... | @@ -35,17 +28,7 @@ test "string escapes" { | ... | @@ -35,17 +28,7 @@ test "string escapes" { |
| 35 | try expectEqualStrings("\u{1234}\u{069}\u{1}", "\xe1\x88\xb4\x69\x01"); | 28 | try expectEqualStrings("\u{1234}\u{069}\u{1}", "\xe1\x88\xb4\x69\x01"); |
| 36 | } | 29 | } |
| 37 | 30 | ||
| 38 | test "multiline string literal is null terminated" { | 31 | test "explicit cast optional pointers" { |
| 39 | const s1 = | ||
| 40 | \\one | ||
| 41 | \\two) | ||
| 42 | \\three | ||
| 43 | ; | ||
| 44 | const s2 = "one\ntwo)\nthree"; | ||
| 45 | try expect(std.cstr.cmp(s1, s2) == 0); | ||
| 46 | } | ||
| 47 | |||
| 48 | test "explicit cast maybe pointers" { | ||
| 49 | const a: ?*i32 = undefined; | 32 | const a: ?*i32 = undefined; |
| 50 | const b: ?*f32 = @ptrCast(?*f32, a); | 33 | const b: ?*f32 = @ptrCast(?*f32, a); |
| 51 | _ = b; | 34 | _ = b; |
| ... | @@ -159,22 +142,6 @@ export fn testPackedStuff(a: *const PackedStruct, b: *const PackedUnion) void { | ... | @@ -159,22 +142,6 @@ export fn testPackedStuff(a: *const PackedStruct, b: *const PackedUnion) void { |
| 159 | } | 142 | } |
| 160 | } | 143 | } |
| 161 | 144 | ||
| 162 | test "self reference through fn ptr field" { | ||
| 163 | const S = struct { | ||
| 164 | const A = struct { | ||
| 165 | f: fn (A) u8, | ||
| 166 | }; | ||
| 167 | |||
| 168 | fn foo(a: A) u8 { | ||
| 169 | _ = a; | ||
| 170 | return 12; | ||
| 171 | } | ||
| 172 | }; | ||
| 173 | var a: S.A = undefined; | ||
| 174 | a.f = S.foo; | ||
| 175 | try expect(a.f(a) == 12); | ||
| 176 | } | ||
| 177 | |||
| 178 | test "thread local variable" { | 145 | test "thread local variable" { |
| 179 | const S = struct { | 146 | const S = struct { |
| 180 | threadlocal var t: i32 = 1234; | 147 | threadlocal var t: i32 = 1234; |
| ... | @@ -183,19 +150,6 @@ test "thread local variable" { | ... | @@ -183,19 +150,6 @@ test "thread local variable" { |
| 183 | try expect(S.t == 1235); | 150 | try expect(S.t == 1235); |
| 184 | } | 151 | } |
| 185 | 152 | ||
| 186 | test "nested optional field in struct" { | ||
| 187 | const S2 = struct { | ||
| 188 | y: u8, | ||
| 189 | }; | ||
| 190 | const S1 = struct { | ||
| 191 | x: ?S2, | ||
| 192 | }; | ||
| 193 | var s = S1{ | ||
| 194 | .x = S2{ .y = 127 }, | ||
| 195 | }; | ||
| 196 | try expect(s.x.?.y == 127); | ||
| 197 | } | ||
| 198 | |||
| 199 | fn maybe(x: bool) anyerror!?u32 { | 153 | fn maybe(x: bool) anyerror!?u32 { |
| 200 | return switch (x) { | 154 | return switch (x) { |
| 201 | true => @as(u32, 42), | 155 | true => @as(u32, 42), |
test/behavior/optional.zig+34| ... | @@ -2,3 +2,37 @@ const std = @import("std"); | ... | @@ -2,3 +2,37 @@ const std = @import("std"); |
| 2 | const testing = std.testing; | 2 | const testing = std.testing; |
| 3 | const expect = testing.expect; | 3 | const expect = testing.expect; |
| 4 | const expectEqual = testing.expectEqual; | 4 | const expectEqual = testing.expectEqual; |
| 5 | |||
| 6 | test "passing an optional integer as a parameter" { | ||
| 7 | const S = struct { | ||
| 8 | fn entry() bool { | ||
| 9 | var x: i32 = 1234; | ||
| 10 | return foo(x); | ||
| 11 | } | ||
| 12 | |||
| 13 | fn foo(x: ?i32) bool { | ||
| 14 | return x.? == 1234; | ||
| 15 | } | ||
| 16 | }; | ||
| 17 | try expect(S.entry()); | ||
| 18 | comptime try expect(S.entry()); | ||
| 19 | } | ||
| 20 | |||
| 21 | test "self-referential struct through a slice of optional" { | ||
| 22 | const S = struct { | ||
| 23 | const Node = struct { | ||
| 24 | children: []?Node, | ||
| 25 | data: ?u8, | ||
| 26 | |||
| 27 | fn new() Node { | ||
| 28 | return Node{ | ||
| 29 | .children = undefined, | ||
| 30 | .data = null, | ||
| 31 | }; | ||
| 32 | } | ||
| 33 | }; | ||
| 34 | }; | ||
| 35 | |||
| 36 | var n = S.Node.new(); | ||
| 37 | try expect(n.data == null); | ||
| 38 | } |
test/behavior/optional_stage1.zig-34| ... | @@ -83,21 +83,6 @@ fn test_cmp_optional_non_optional() !void { | ... | @@ -83,21 +83,6 @@ fn test_cmp_optional_non_optional() !void { |
| 83 | }; | 83 | }; |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | test "passing an optional integer as a parameter" { | ||
| 87 | const S = struct { | ||
| 88 | fn entry() bool { | ||
| 89 | var x: i32 = 1234; | ||
| 90 | return foo(x); | ||
| 91 | } | ||
| 92 | |||
| 93 | fn foo(x: ?i32) bool { | ||
| 94 | return x.? == 1234; | ||
| 95 | } | ||
| 96 | }; | ||
| 97 | try expect(S.entry()); | ||
| 98 | comptime try expect(S.entry()); | ||
| 99 | } | ||
| 100 | |||
| 101 | test "unwrap function call with optional pointer return value" { | 86 | test "unwrap function call with optional pointer return value" { |
| 102 | const S = struct { | 87 | const S = struct { |
| 103 | fn entry() !void { | 88 | fn entry() !void { |
| ... | @@ -139,25 +124,6 @@ test "nested orelse" { | ... | @@ -139,25 +124,6 @@ test "nested orelse" { |
| 139 | comptime try S.entry(); | 124 | comptime try S.entry(); |
| 140 | } | 125 | } |
| 141 | 126 | ||
| 142 | test "self-referential struct through a slice of optional" { | ||
| 143 | const S = struct { | ||
| 144 | const Node = struct { | ||
| 145 | children: []?Node, | ||
| 146 | data: ?u8, | ||
| 147 | |||
| 148 | fn new() Node { | ||
| 149 | return Node{ | ||
| 150 | .children = undefined, | ||
| 151 | .data = null, | ||
| 152 | }; | ||
| 153 | } | ||
| 154 | }; | ||
| 155 | }; | ||
| 156 | |||
| 157 | var n = S.Node.new(); | ||
| 158 | try expect(n.data == null); | ||
| 159 | } | ||
| 160 | |||
| 161 | test "assigning to an unwrapped optional field in an inline loop" { | 127 | test "assigning to an unwrapped optional field in an inline loop" { |
| 162 | comptime var maybe_pos_arg: ?comptime_int = null; | 128 | comptime var maybe_pos_arg: ?comptime_int = null; |
| 163 | inline for ("ab") |x| { | 129 | inline for ("ab") |x| { |
test/behavior/slice_stage1.zig+92| ... | @@ -20,6 +20,23 @@ test "slicing" { | ... | @@ -20,6 +20,23 @@ test "slicing" { |
| 20 | if (slice_rest.len != 10) unreachable; | 20 | if (slice_rest.len != 10) unreachable; |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | test "const slice" { | ||
| 24 | comptime { | ||
| 25 | const a = "1234567890"; | ||
| 26 | try expect(a.len == 10); | ||
| 27 | const b = a[1..2]; | ||
| 28 | try expect(b.len == 1); | ||
| 29 | try expect(b[0] == '2'); | ||
| 30 | } | ||
| 31 | } | ||
| 32 | |||
| 33 | test "comptime slice of undefined pointer of length 0" { | ||
| 34 | const slice1 = @as([*]i32, undefined)[0..0]; | ||
| 35 | try expect(slice1.len == 0); | ||
| 36 | const slice2 = @as([*]i32, undefined)[100..100]; | ||
| 37 | try expect(slice2.len == 0); | ||
| 38 | } | ||
| 39 | |||
| 23 | test "slicing zero length array" { | 40 | test "slicing zero length array" { |
| 24 | const s1 = ""[0..]; | 41 | const s1 = ""[0..]; |
| 25 | const s2 = ([_]u32{})[0..]; | 42 | const s2 = ([_]u32{})[0..]; |
| ... | @@ -389,3 +406,78 @@ test "type coercion of pointer to anon struct literal to pointer to slice" { | ... | @@ -389,3 +406,78 @@ test "type coercion of pointer to anon struct literal to pointer to slice" { |
| 389 | // try S.doTheTest(); | 406 | // try S.doTheTest(); |
| 390 | comptime try S.doTheTest(); | 407 | comptime try S.doTheTest(); |
| 391 | } | 408 | } |
| 409 | |||
| 410 | test "comptime slice of slice preserves comptime var" { | ||
| 411 | comptime { | ||
| 412 | var buff: [10]u8 = undefined; | ||
| 413 | buff[0..][0..][0] = 1; | ||
| 414 | try expect(buff[0..][0..][0] == 1); | ||
| 415 | } | ||
| 416 | } | ||
| 417 | |||
| 418 | test "comptime slice of pointer preserves comptime var" { | ||
| 419 | comptime { | ||
| 420 | var buff: [10]u8 = undefined; | ||
| 421 | var a = @ptrCast([*]u8, &buff); | ||
| 422 | a[0..1][0] = 1; | ||
| 423 | try expect(buff[0..][0..][0] == 1); | ||
| 424 | } | ||
| 425 | } | ||
| 426 | |||
| 427 | test "array concat of slices gives slice" { | ||
| 428 | comptime { | ||
| 429 | var a: []const u8 = "aoeu"; | ||
| 430 | var b: []const u8 = "asdf"; | ||
| 431 | const c = a ++ b; | ||
| 432 | try expect(std.mem.eql(u8, c, "aoeuasdf")); | ||
| 433 | } | ||
| 434 | } | ||
| 435 | |||
| 436 | test "slice of type" { | ||
| 437 | comptime { | ||
| 438 | var types_array = [_]type{ i32, f64, type }; | ||
| 439 | for (types_array) |T, i| { | ||
| 440 | switch (i) { | ||
| 441 | 0 => try expect(T == i32), | ||
| 442 | 1 => try expect(T == f64), | ||
| 443 | 2 => try expect(T == type), | ||
| 444 | else => unreachable, | ||
| 445 | } | ||
| 446 | } | ||
| 447 | for (types_array[0..]) |T, i| { | ||
| 448 | switch (i) { | ||
| 449 | 0 => try expect(T == i32), | ||
| 450 | 1 => try expect(T == f64), | ||
| 451 | 2 => try expect(T == type), | ||
| 452 | else => unreachable, | ||
| 453 | } | ||
| 454 | } | ||
| 455 | } | ||
| 456 | } | ||
| 457 | |||
| 458 | test "comptime pointer cast array and then slice" { | ||
| 459 | const array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 }; | ||
| 460 | |||
| 461 | const ptrA: [*]const u8 = @ptrCast([*]const u8, &array); | ||
| 462 | const sliceA: []const u8 = ptrA[0..2]; | ||
| 463 | |||
| 464 | const ptrB: [*]const u8 = &array; | ||
| 465 | const sliceB: []const u8 = ptrB[0..2]; | ||
| 466 | |||
| 467 | try expect(sliceA[1] == 2); | ||
| 468 | try expect(sliceB[1] == 2); | ||
| 469 | } | ||
| 470 | |||
| 471 | test "slice bounds in comptime concatenation" { | ||
| 472 | const bs = comptime blk: { | ||
| 473 | const b = "........1........"; | ||
| 474 | break :blk b[8..9]; | ||
| 475 | }; | ||
| 476 | const str = "" ++ bs; | ||
| 477 | try expect(str.len == 1); | ||
| 478 | try expect(std.mem.eql(u8, str, "1")); | ||
| 479 | |||
| 480 | const str2 = bs ++ ""; | ||
| 481 | try expect(str2.len == 1); | ||
| 482 | try expect(std.mem.eql(u8, str2, "1")); | ||
| 483 | } |
test/behavior/while.zig+88| ... | @@ -111,3 +111,91 @@ test "while copies its payload" { | ... | @@ -111,3 +111,91 @@ test "while copies its payload" { |
| 111 | try S.doTheTest(); | 111 | try S.doTheTest(); |
| 112 | comptime try S.doTheTest(); | 112 | comptime try S.doTheTest(); |
| 113 | } | 113 | } |
| 114 | |||
| 115 | test "continue and break" { | ||
| 116 | try runContinueAndBreakTest(); | ||
| 117 | try expect(continue_and_break_counter == 8); | ||
| 118 | } | ||
| 119 | var continue_and_break_counter: i32 = 0; | ||
| 120 | fn runContinueAndBreakTest() !void { | ||
| 121 | var i: i32 = 0; | ||
| 122 | while (true) { | ||
| 123 | continue_and_break_counter += 2; | ||
| 124 | i += 1; | ||
| 125 | if (i < 4) { | ||
| 126 | continue; | ||
| 127 | } | ||
| 128 | break; | ||
| 129 | } | ||
| 130 | try expect(i == 4); | ||
| 131 | } | ||
| 132 | |||
| 133 | test "while with optional as condition" { | ||
| 134 | numbers_left = 10; | ||
| 135 | var sum: i32 = 0; | ||
| 136 | while (getNumberOrNull()) |value| { | ||
| 137 | sum += value; | ||
| 138 | } | ||
| 139 | try expect(sum == 45); | ||
| 140 | } | ||
| 141 | |||
| 142 | test "while with optional as condition with else" { | ||
| 143 | numbers_left = 10; | ||
| 144 | var sum: i32 = 0; | ||
| 145 | var got_else: i32 = 0; | ||
| 146 | while (getNumberOrNull()) |value| { | ||
| 147 | sum += value; | ||
| 148 | try expect(got_else == 0); | ||
| 149 | } else { | ||
| 150 | got_else += 1; | ||
| 151 | } | ||
| 152 | try expect(sum == 45); | ||
| 153 | try expect(got_else == 1); | ||
| 154 | } | ||
| 155 | |||
| 156 | test "while on bool with else result follow else prong" { | ||
| 157 | const result = while (returnFalse()) { | ||
| 158 | break @as(i32, 10); | ||
| 159 | } else @as(i32, 2); | ||
| 160 | try expect(result == 2); | ||
| 161 | } | ||
| 162 | |||
| 163 | test "while on bool with else result follow break prong" { | ||
| 164 | const result = while (returnTrue()) { | ||
| 165 | break @as(i32, 10); | ||
| 166 | } else @as(i32, 2); | ||
| 167 | try expect(result == 10); | ||
| 168 | } | ||
| 169 | |||
| 170 | test "while on optional with else result follow else prong" { | ||
| 171 | const result = while (returnNull()) |value| { | ||
| 172 | break value; | ||
| 173 | } else @as(i32, 2); | ||
| 174 | try expect(result == 2); | ||
| 175 | } | ||
| 176 | |||
| 177 | test "while on optional with else result follow break prong" { | ||
| 178 | const result = while (returnOptional(10)) |value| { | ||
| 179 | break value; | ||
| 180 | } else @as(i32, 2); | ||
| 181 | try expect(result == 10); | ||
| 182 | } | ||
| 183 | |||
| 184 | fn returnNull() ?i32 { | ||
| 185 | return null; | ||
| 186 | } | ||
| 187 | fn returnOptional(x: i32) ?i32 { | ||
| 188 | return x; | ||
| 189 | } | ||
| 190 | fn returnError() anyerror!i32 { | ||
| 191 | return error.YouWantedAnError; | ||
| 192 | } | ||
| 193 | fn returnSuccess(x: i32) anyerror!i32 { | ||
| 194 | return x; | ||
| 195 | } | ||
| 196 | fn returnFalse() bool { | ||
| 197 | return false; | ||
| 198 | } | ||
| 199 | fn returnTrue() bool { | ||
| 200 | return true; | ||
| 201 | } |
test/behavior/while_stage1.zig-69| ... | @@ -1,24 +1,6 @@ | ... | @@ -1,24 +1,6 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const expect = std.testing.expect; | 2 | const expect = std.testing.expect; |
| 3 | 3 | ||
| 4 | test "continue and break" { | ||
| 5 | try runContinueAndBreakTest(); | ||
| 6 | try expect(continue_and_break_counter == 8); | ||
| 7 | } | ||
| 8 | var continue_and_break_counter: i32 = 0; | ||
| 9 | fn runContinueAndBreakTest() !void { | ||
| 10 | var i: i32 = 0; | ||
| 11 | while (true) { | ||
| 12 | continue_and_break_counter += 2; | ||
| 13 | i += 1; | ||
| 14 | if (i < 4) { | ||
| 15 | continue; | ||
| 16 | } | ||
| 17 | break; | ||
| 18 | } | ||
| 19 | try expect(i == 4); | ||
| 20 | } | ||
| 21 | |||
| 22 | test "return with implicit cast from while loop" { | 4 | test "return with implicit cast from while loop" { |
| 23 | returnWithImplicitCastFromWhileLoopTest() catch unreachable; | 5 | returnWithImplicitCastFromWhileLoopTest() catch unreachable; |
| 24 | } | 6 | } |
| ... | @@ -28,29 +10,6 @@ fn returnWithImplicitCastFromWhileLoopTest() anyerror!void { | ... | @@ -28,29 +10,6 @@ fn returnWithImplicitCastFromWhileLoopTest() anyerror!void { |
| 28 | } | 10 | } |
| 29 | } | 11 | } |
| 30 | 12 | ||
| 31 | test "while with optional as condition" { | ||
| 32 | numbers_left = 10; | ||
| 33 | var sum: i32 = 0; | ||
| 34 | while (getNumberOrNull()) |value| { | ||
| 35 | sum += value; | ||
| 36 | } | ||
| 37 | try expect(sum == 45); | ||
| 38 | } | ||
| 39 | |||
| 40 | test "while with optional as condition with else" { | ||
| 41 | numbers_left = 10; | ||
| 42 | var sum: i32 = 0; | ||
| 43 | var got_else: i32 = 0; | ||
| 44 | while (getNumberOrNull()) |value| { | ||
| 45 | sum += value; | ||
| 46 | try expect(got_else == 0); | ||
| 47 | } else { | ||
| 48 | got_else += 1; | ||
| 49 | } | ||
| 50 | try expect(sum == 45); | ||
| 51 | try expect(got_else == 1); | ||
| 52 | } | ||
| 53 | |||
| 54 | test "while with error union condition" { | 13 | test "while with error union condition" { |
| 55 | numbers_left = 10; | 14 | numbers_left = 10; |
| 56 | var sum: i32 = 0; | 15 | var sum: i32 = 0; |
| ... | @@ -79,20 +38,6 @@ fn getNumberOrNull() ?i32 { | ... | @@ -79,20 +38,6 @@ fn getNumberOrNull() ?i32 { |
| 79 | }; | 38 | }; |
| 80 | } | 39 | } |
| 81 | 40 | ||
| 82 | test "while on optional with else result follow else prong" { | ||
| 83 | const result = while (returnNull()) |value| { | ||
| 84 | break value; | ||
| 85 | } else @as(i32, 2); | ||
| 86 | try expect(result == 2); | ||
| 87 | } | ||
| 88 | |||
| 89 | test "while on optional with else result follow break prong" { | ||
| 90 | const result = while (returnOptional(10)) |value| { | ||
| 91 | break value; | ||
| 92 | } else @as(i32, 2); | ||
| 93 | try expect(result == 10); | ||
| 94 | } | ||
| 95 | |||
| 96 | test "while on error union with else result follow else prong" { | 41 | test "while on error union with else result follow else prong" { |
| 97 | const result = while (returnError()) |value| { | 42 | const result = while (returnError()) |value| { |
| 98 | break value; | 43 | break value; |
| ... | @@ -107,20 +52,6 @@ test "while on error union with else result follow break prong" { | ... | @@ -107,20 +52,6 @@ test "while on error union with else result follow break prong" { |
| 107 | try expect(result == 10); | 52 | try expect(result == 10); |
| 108 | } | 53 | } |
| 109 | 54 | ||
| 110 | test "while on bool with else result follow else prong" { | ||
| 111 | const result = while (returnFalse()) { | ||
| 112 | break @as(i32, 10); | ||
| 113 | } else @as(i32, 2); | ||
| 114 | try expect(result == 2); | ||
| 115 | } | ||
| 116 | |||
| 117 | test "while on bool with else result follow break prong" { | ||
| 118 | const result = while (returnTrue()) { | ||
| 119 | break @as(i32, 10); | ||
| 120 | } else @as(i32, 2); | ||
| 121 | try expect(result == 10); | ||
| 122 | } | ||
| 123 | |||
| 124 | fn returnNull() ?i32 { | 55 | fn returnNull() ?i32 { |
| 125 | return null; | 56 | return null; |
| 126 | } | 57 | } |