authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-04 20:43:49-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-04 20:43:49-04:00
logb5d07297dec61a3993dfe91ceee2c87672db1e8e
tree519d097fcdfe121e38814a080868a85f5b1f9e64
parent9665cfe027c70a84cb6351ea6ecb833a728736aa
parent8c39cdc89f2ae7fc25c3856e7c4c6b4662ac8a80

Merge remote-tracking branch 'origin/master' into llvm7


13 files changed, 168 insertions(+), 75 deletions(-)

.gitattributes+1
...@@ -1 +1,2 @@...@@ -1 +1,2 @@
1*.zig text eol=lf 1*.zig text eol=lf
2langref.html.in text eol=lf
doc/langref.html.in+95-32
...@@ -616,6 +616,17 @@ test "init with undefined" {...@@ -616,6 +616,17 @@ test "init with undefined" {
616 assert(x == 1);616 assert(x == 1);
617}617}
618 {#code_end#}618 {#code_end#}
619 <p>
620 <code>undefined</code> can be {#link|implicitly cast|Implicit Casts#} to any type.
621 Once this happens, it is no longer possible to detect that the value is <code>undefined</code>.
622 <code>undefined</code> means the value could be anything, even something that is nonsense
623 according to the type. Translated into English, <code>undefined</code> means "Not a meaningful
624 value. Using this value would be a bug. The value will be unused, or overwritten before being used."
625 </p>
626 <p>
627 In {#link|Debug#} mode, Zig writes <code>0xaa</code> bytes to undefined memory. This is to catch
628 bugs early, and to help detect use of undefined memory in a debugger.
629 </p>
619 {#header_close#}630 {#header_close#}
620 {#header_close#}631 {#header_close#}
621 {#header_close#}632 {#header_close#}
...@@ -2237,21 +2248,28 @@ test "switch inside function" {...@@ -2237,21 +2248,28 @@ test "switch inside function" {
2237 {#see_also|comptime|enum|@compileError|Compile Variables#}2248 {#see_also|comptime|enum|@compileError|Compile Variables#}
2238 {#header_close#}2249 {#header_close#}
2239 {#header_open|while#}2250 {#header_open|while#}
2251 <p>
2252 A while loop is used to repeatedly execute an expression until
2253 some condition is no longer true.
2254 </p>
2240 {#code_begin|test|while#}2255 {#code_begin|test|while#}
2241const assert = @import("std").debug.assert;2256const assert = @import("std").debug.assert;
22422257
2243test "while basic" {2258test "while basic" {
2244 // A while loop is used to repeatedly execute an expression until
2245 // some condition is no longer true.
2246 var i: usize = 0;2259 var i: usize = 0;
2247 while (i < 10) {2260 while (i < 10) {
2248 i += 1;2261 i += 1;
2249 }2262 }
2250 assert(i == 10);2263 assert(i == 10);
2251}2264}
2265 {#code_end#}
2266 <p>
2267 Use <code>break</code> to exit a while loop early.
2268 </p>
2269 {#code_begin|test|while#}
2270const assert = @import("std").debug.assert;
22522271
2253test "while break" {2272test "while break" {
2254 // You can use break to exit a while loop early.
2255 var i: usize = 0;2273 var i: usize = 0;
2256 while (true) {2274 while (true) {
2257 if (i == 10)2275 if (i == 10)
...@@ -2260,9 +2278,14 @@ test "while break" {...@@ -2260,9 +2278,14 @@ test "while break" {
2260 }2278 }
2261 assert(i == 10);2279 assert(i == 10);
2262}2280}
2281 {#code_end#}
2282 <p>
2283 Use <code>continue</code> to jump back to the beginning of the loop.
2284 </p>
2285 {#code_begin|test|while#}
2286const assert = @import("std").debug.assert;
22632287
2264test "while continue" {2288test "while continue" {
2265 // You can use continue to jump back to the beginning of the loop.
2266 var i: usize = 0;2289 var i: usize = 0;
2267 while (true) {2290 while (true) {
2268 i += 1;2291 i += 1;
...@@ -2272,18 +2295,21 @@ test "while continue" {...@@ -2272,18 +2295,21 @@ test "while continue" {
2272 }2295 }
2273 assert(i == 10);2296 assert(i == 10);
2274}2297}
2298 {#code_end#}
2299 <p>
2300 While loops support a continue expression which is executed when the loop
2301 is continued. The <code>continue</code> keyword respects this expression.
2302 </p>
2303 {#code_begin|test|while#}
2304const assert = @import("std").debug.assert;
22752305
2276test "while loop continuation expression" {2306test "while loop continuation expression" {
2277 // You can give an expression to the while loop to execute when
2278 // the loop is continued. This is respected by the continue control flow.
2279 var i: usize = 0;2307 var i: usize = 0;
2280 while (i < 10) : (i += 1) {}2308 while (i < 10) : (i += 1) {}
2281 assert(i == 10);2309 assert(i == 10);
2282}2310}
22832311
2284test "while loop continuation expression, more complicated" {2312test "while loop continuation expression, more complicated" {
2285 // More complex blocks can be used as an expression in the loop continue
2286 // expression.
2287 var i1: usize = 1;2313 var i1: usize = 1;
2288 var j1: usize = 1;2314 var j1: usize = 1;
2289 while (i1 * j1 < 2000) : ({ i1 *= 2; j1 *= 3; }) {2315 while (i1 * j1 < 2000) : ({ i1 *= 2; j1 *= 3; }) {
...@@ -2291,6 +2317,20 @@ test "while loop continuation expression, more complicated" {...@@ -2291,6 +2317,20 @@ test "while loop continuation expression, more complicated" {
2291 assert(my_ij1 < 2000);2317 assert(my_ij1 < 2000);
2292 }2318 }
2293}2319}
2320 {#code_end#}
2321 <p>
2322 While loops are expressions. The result of the expression is the
2323 result of the <code>else</code> clause of a while loop, which is executed when
2324 the condition of the while loop is tested as false.
2325 </p>
2326 <p>
2327 <code>break</code>, like <code>return</code>, accepts a value
2328 parameter. This is the result of the <code>while</code> expression.
2329 When you <code>break</code> from a while loop, the <code>else</code> branch is not
2330 evaluated.
2331 </p>
2332 {#code_begin|test|while#}
2333const assert = @import("std").debug.assert;
22942334
2295test "while else" {2335test "while else" {
2296 assert(rangeHasNumber(0, 10, 5));2336 assert(rangeHasNumber(0, 10, 5));
...@@ -2299,24 +2339,31 @@ test "while else" {...@@ -2299,24 +2339,31 @@ test "while else" {
22992339
2300fn rangeHasNumber(begin: usize, end: usize, number: usize) bool {2340fn rangeHasNumber(begin: usize, end: usize, number: usize) bool {
2301 var i = begin;2341 var i = begin;
2302 // While loops are expressions. The result of the expression is the
2303 // result of the else clause of a while loop, which is executed when
2304 // the condition of the while loop is tested as false.
2305 return while (i < end) : (i += 1) {2342 return while (i < end) : (i += 1) {
2306 if (i == number) {2343 if (i == number) {
2307 // break expressions, like return expressions, accept a value
2308 // parameter. This is the result of the while expression.
2309 // When you break from a while loop, the else branch is not
2310 // evaluated.
2311 break true;2344 break true;
2312 }2345 }
2313 } else false;2346 } else false;
2314}2347}
2348 {#code_end#}
2349 {#header_open|while with Optionals#}
2350 <p>
2351 Just like {#link|if#} expressions, while loops can take an optional as the
2352 condition and capture the payload. When {#link|null#} is encountered the loop
2353 exits.
2354 </p>
2355 <p>
2356 When the <code>|x|</code> syntax is present on a <code>while</code> expression,
2357 the while condition must have an {#link|Optional Type#}.
2358 </p>
2359 <p>
2360 The <code>else</code> branch is allowed on optional iteration. In this case, it will
2361 be executed on the first null value encountered.
2362 </p>
2363 {#code_begin|test|while#}
2364const assert = @import("std").debug.assert;
23152365
2316test "while null capture" {2366test "while null capture" {
2317 // Just like if expressions, while loops can take an optional as the
2318 // condition and capture the payload. When null is encountered the loop
2319 // exits.
2320 var sum1: u32 = 0;2367 var sum1: u32 = 0;
2321 numbers_left = 3;2368 numbers_left = 3;
2322 while (eventuallyNullSequence()) |value| {2369 while (eventuallyNullSequence()) |value| {
...@@ -2324,8 +2371,6 @@ test "while null capture" {...@@ -2324,8 +2371,6 @@ test "while null capture" {
2324 }2371 }
2325 assert(sum1 == 3);2372 assert(sum1 == 3);
23262373
2327 // The else branch is allowed on optional iteration. In this case, it will
2328 // be executed on the first null value encountered.
2329 var sum2: u32 = 0;2374 var sum2: u32 = 0;
2330 numbers_left = 3;2375 numbers_left = 3;
2331 while (eventuallyNullSequence()) |value| {2376 while (eventuallyNullSequence()) |value| {
...@@ -2333,18 +2378,6 @@ test "while null capture" {...@@ -2333,18 +2378,6 @@ test "while null capture" {
2333 } else {2378 } else {
2334 assert(sum1 == 3);2379 assert(sum1 == 3);
2335 }2380 }
2336
2337 // Just like if expressions, while loops can also take an error union as
2338 // the condition and capture the payload or the error code. When the
2339 // condition results in an error code the else branch is evaluated and
2340 // the loop is finished.
2341 var sum3: u32 = 0;
2342 numbers_left = 3;
2343 while (eventuallyErrorSequence()) |value| {
2344 sum3 += value;
2345 } else |err| {
2346 assert(err == error.ReachedZero);
2347 }
2348}2381}
23492382
2350var numbers_left: u32 = undefined;2383var numbers_left: u32 = undefined;
...@@ -2355,6 +2388,35 @@ fn eventuallyNullSequence() ?u32 {...@@ -2355,6 +2388,35 @@ fn eventuallyNullSequence() ?u32 {
2355 };2388 };
2356}2389}
23572390
2391 {#code_end#}
2392 {#header_close#}
2393
2394 {#header_open|while with Error Unions#}
2395 <p>
2396 Just like {#link|if#} expressions, while loops can take an error union as
2397 the condition and capture the payload or the error code. When the
2398 condition results in an error code the else branch is evaluated and
2399 the loop is finished.
2400 </p>
2401 <p>
2402 When the <code>else |x|</code> syntax is present on a <code>while</code> expression,
2403 the while condition must have an {#link|Error Union Type#}.
2404 </p>
2405 {#code_begin|test|while#}
2406const assert = @import("std").debug.assert;
2407
2408test "while error union capture" {
2409 var sum1: u32 = 0;
2410 numbers_left = 3;
2411 while (eventuallyErrorSequence()) |value| {
2412 sum1 += value;
2413 } else |err| {
2414 assert(err == error.ReachedZero);
2415 }
2416}
2417
2418var numbers_left: u32 = undefined;
2419
2358fn eventuallyErrorSequence() error!u32 {2420fn eventuallyErrorSequence() error!u32 {
2359 return if (numbers_left == 0) error.ReachedZero else blk: {2421 return if (numbers_left == 0) error.ReachedZero else blk: {
2360 numbers_left -= 1;2422 numbers_left -= 1;
...@@ -2362,6 +2424,7 @@ fn eventuallyErrorSequence() error!u32 {...@@ -2362,6 +2424,7 @@ fn eventuallyErrorSequence() error!u32 {
2362 };2424 };
2363}2425}
2364 {#code_end#}2426 {#code_end#}
2427 {#header_close#}
23652428
2366 {#header_open|inline while#}2429 {#header_open|inline while#}
2367 <p>2430 <p>
src/analyze.cpp+2-10
...@@ -4417,22 +4417,14 @@ Buf *get_linux_libc_include_path(void) {...@@ -4417,22 +4417,14 @@ Buf *get_linux_libc_include_path(void) {
4417 }4417 }
4418 char *prev_newline = buf_ptr(out_stderr);4418 char *prev_newline = buf_ptr(out_stderr);
4419 ZigList<const char *> search_paths = {};4419 ZigList<const char *> search_paths = {};
4420 bool found_search_paths = false;
4421 for (;;) {4420 for (;;) {
4422 char *newline = strchr(prev_newline, '\n');4421 char *newline = strchr(prev_newline, '\n');
4423 if (newline == nullptr) {4422 if (newline == nullptr) {
4424 zig_panic("unable to determine libc include path: bad output from C compiler command");4423 break;
4425 }4424 }
4426 *newline = 0;4425 *newline = 0;
4427 if (found_search_paths) {4426 if (prev_newline[0] == ' ') {
4428 if (strcmp(prev_newline, "End of search list.") == 0) {
4429 break;
4430 }
4431 search_paths.append(prev_newline);4427 search_paths.append(prev_newline);
4432 } else {
4433 if (strcmp(prev_newline, "#include <...> search starts here:") == 0) {
4434 found_search_paths = true;
4435 }
4436 }4428 }
4437 prev_newline = newline + 1;4429 prev_newline = newline + 1;
4438 }4430 }
src/ir.cpp+4-8
...@@ -6674,7 +6674,10 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *parent_scope, Ast...@@ -6674,7 +6674,10 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *parent_scope, Ast
6674 }6674 }
6675 Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME);6675 Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME);
6676 IrInstruction *promise_result_ptr = ir_build_field_ptr(irb, parent_scope, node, coro_promise_ptr, result_field_name);6676 IrInstruction *promise_result_ptr = ir_build_field_ptr(irb, parent_scope, node, coro_promise_ptr, result_field_name);
6677 // If the type of the result handle_is_ptr then this does not actually perform a load. But we need it to,
6678 // because we're about to destroy the memory. So we store it into our result variable.
6677 IrInstruction *no_suspend_result = ir_build_load_ptr(irb, parent_scope, node, promise_result_ptr);6679 IrInstruction *no_suspend_result = ir_build_load_ptr(irb, parent_scope, node, promise_result_ptr);
6680 ir_build_store_ptr(irb, parent_scope, node, my_result_var_ptr, no_suspend_result);
6678 ir_build_cancel(irb, parent_scope, node, target_inst);6681 ir_build_cancel(irb, parent_scope, node, target_inst);
6679 ir_build_br(irb, parent_scope, node, merge_block, const_bool_false);6682 ir_build_br(irb, parent_scope, node, merge_block, const_bool_false);
66806683
...@@ -6696,17 +6699,10 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *parent_scope, Ast...@@ -6696,17 +6699,10 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *parent_scope, Ast
6696 ir_mark_gen(ir_build_br(irb, parent_scope, node, irb->exec->coro_final_cleanup_block, const_bool_false));6699 ir_mark_gen(ir_build_br(irb, parent_scope, node, irb->exec->coro_final_cleanup_block, const_bool_false));
66976700
6698 ir_set_cursor_at_end_and_append_block(irb, resume_block);6701 ir_set_cursor_at_end_and_append_block(irb, resume_block);
6699 IrInstruction *yes_suspend_result = ir_build_load_ptr(irb, parent_scope, node, my_result_var_ptr);
6700 ir_build_br(irb, parent_scope, node, merge_block, const_bool_false);6702 ir_build_br(irb, parent_scope, node, merge_block, const_bool_false);
67016703
6702 ir_set_cursor_at_end_and_append_block(irb, merge_block);6704 ir_set_cursor_at_end_and_append_block(irb, merge_block);
6703 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2);6705 return ir_build_load_ptr(irb, parent_scope, node, my_result_var_ptr);
6704 IrInstruction **incoming_values = allocate<IrInstruction *>(2);
6705 incoming_blocks[0] = resume_block;
6706 incoming_values[0] = yes_suspend_result;
6707 incoming_blocks[1] = no_suspend_block;
6708 incoming_values[1] = no_suspend_result;
6709 return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values);
6710}6706}
67116707
6712static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNode *node) {6708static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
std/mem.zig+1-1
...@@ -34,7 +34,7 @@ pub const Allocator = struct {...@@ -34,7 +34,7 @@ pub const Allocator = struct {
34 /// Call `destroy` with the result34 /// Call `destroy` with the result
35 pub fn create(self: *Allocator, init: var) Error!*@typeOf(init) {35 pub fn create(self: *Allocator, init: var) Error!*@typeOf(init) {
36 const T = @typeOf(init);36 const T = @typeOf(init);
37 if (@sizeOf(T) == 0) return &{};37 if (@sizeOf(T) == 0) return &(T{});
38 const slice = try self.alloc(T, 1);38 const slice = try self.alloc(T, 1);
39 const ptr = &slice[0];39 const ptr = &slice[0];
40 ptr.* = init;40 ptr.* = init;
std/special/compiler_rt/comparetf2.zig+2-2
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1// TODO https://github.com/ziglang/zig/issues/3051// TODO https://github.com/ziglang/zig/issues/641
2// and then make the return types of some of these functions the enum instead of c_int2// and then make the return types of some of these functions the enum instead of c_int
3const LE_LESS = c_int(-1);3const LE_LESS = c_int(-1);
4const LE_EQUAL = c_int(0);4const LE_EQUAL = c_int(0);
...@@ -56,7 +56,7 @@ pub extern fn __letf2(a: f128, b: f128) c_int {...@@ -56,7 +56,7 @@ pub extern fn __letf2(a: f128, b: f128) c_int {
56 LE_GREATER;56 LE_GREATER;
57}57}
5858
59// TODO https://github.com/ziglang/zig/issues/30559// TODO https://github.com/ziglang/zig/issues/641
60// and then make the return types of some of these functions the enum instead of c_int60// and then make the return types of some of these functions the enum instead of c_int
61const GE_LESS = c_int(-1);61const GE_LESS = c_int(-1);
62const GE_EQUAL = c_int(0);62const GE_EQUAL = c_int(0);
std/special/compiler_rt/fixuint.zig-6
...@@ -44,14 +44,8 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t...@@ -44,14 +44,8 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t
44 // If 0 <= exponent < significandBits, right shift to get the result.44 // If 0 <= exponent < significandBits, right shift to get the result.
45 // Otherwise, shift left.45 // Otherwise, shift left.
46 if (exponent < significandBits) {46 if (exponent < significandBits) {
47 // TODO this is a workaround for the mysterious "integer cast truncated bits"
48 // happening on the next line
49 @setRuntimeSafety(false);
50 return @intCast(fixuint_t, significand >> @intCast(Log2Int(rep_t), significandBits - exponent));47 return @intCast(fixuint_t, significand >> @intCast(Log2Int(rep_t), significandBits - exponent));
51 } else {48 } else {
52 // TODO this is a workaround for the mysterious "integer cast truncated bits"
53 // happening on the next line
54 @setRuntimeSafety(false);
55 return @intCast(fixuint_t, significand) << @intCast(Log2Int(fixuint_t), exponent - significandBits);49 return @intCast(fixuint_t, significand) << @intCast(Log2Int(fixuint_t), exponent - significandBits);
56 }50 }
57}51}
std/special/compiler_rt/fixunstfdi_test.zig+10-11
...@@ -36,15 +36,14 @@ test "fixunstfdi" {...@@ -36,15 +36,14 @@ test "fixunstfdi" {
36 test__fixunstfdi(-0x1.FFFFFFFFFFFFFp+62, 0);36 test__fixunstfdi(-0x1.FFFFFFFFFFFFFp+62, 0);
37 test__fixunstfdi(-0x1.FFFFFFFFFFFFEp+62, 0);37 test__fixunstfdi(-0x1.FFFFFFFFFFFFEp+62, 0);
3838
39 // TODO enable these tests when we can parse f128 float literals39 test__fixunstfdi(0x1.FFFFFFFFFFFFFFFEp+63, 0xFFFFFFFFFFFFFFFF);
40 //test__fixunstfdi(0x1.FFFFFFFFFFFFFFFEp+63, 0xFFFFFFFFFFFFFFFF);40 test__fixunstfdi(0x1.0000000000000002p+63, 0x8000000000000001);
41 //test__fixunstfdi(0x1.0000000000000002p+63, 0x8000000000000001);41 test__fixunstfdi(0x1.0000000000000000p+63, 0x8000000000000000);
42 //test__fixunstfdi(0x1.0000000000000000p+63, 0x8000000000000000);42 test__fixunstfdi(0x1.FFFFFFFFFFFFFFFCp+62, 0x7FFFFFFFFFFFFFFF);
43 //test__fixunstfdi(0x1.FFFFFFFFFFFFFFFCp+62, 0x7FFFFFFFFFFFFFFF);43 test__fixunstfdi(0x1.FFFFFFFFFFFFFFF8p+62, 0x7FFFFFFFFFFFFFFE);
44 //test__fixunstfdi(0x1.FFFFFFFFFFFFFFF8p+62, 0x7FFFFFFFFFFFFFFE);44 test__fixunstfdi(0x1.p+64, 0xFFFFFFFFFFFFFFFF);
45 //test__fixunstfdi(0x1.p+64, 0xFFFFFFFFFFFFFFFF);45
4646 test__fixunstfdi(-0x1.0000000000000000p+63, 0);
47 //test__fixunstfdi(-0x1.0000000000000000p+63, 0);47 test__fixunstfdi(-0x1.FFFFFFFFFFFFFFFCp+62, 0);
48 //test__fixunstfdi(-0x1.FFFFFFFFFFFFFFFCp+62, 0);48 test__fixunstfdi(-0x1.FFFFFFFFFFFFFFF8p+62, 0);
49 //test__fixunstfdi(-0x1.FFFFFFFFFFFFFFF8p+62, 0);
50}49}
std/special/compiler_rt/fixunstfsi_test.zig+2-2
...@@ -11,9 +11,9 @@ const inf128 = @bitCast(f128, u128(0x7fff0000000000000000000000000000));...@@ -11,9 +11,9 @@ const inf128 = @bitCast(f128, u128(0x7fff0000000000000000000000000000));
11test "fixunstfsi" {11test "fixunstfsi" {
12 test__fixunstfsi(inf128, 0xffffffff);12 test__fixunstfsi(inf128, 0xffffffff);
13 test__fixunstfsi(0, 0x0);13 test__fixunstfsi(0, 0x0);
14 //TODO test__fixunstfsi(0x1.23456789abcdefp+5, 0x24);14 test__fixunstfsi(0x1.23456789abcdefp+5, 0x24);
15 test__fixunstfsi(0x1.23456789abcdefp-3, 0x0);15 test__fixunstfsi(0x1.23456789abcdefp-3, 0x0);
16 //TODO test__fixunstfsi(0x1.23456789abcdefp+20, 0x123456);16 test__fixunstfsi(0x1.23456789abcdefp+20, 0x123456);
17 test__fixunstfsi(0x1.23456789abcdefp+40, 0xffffffff);17 test__fixunstfsi(0x1.23456789abcdefp+40, 0xffffffff);
18 test__fixunstfsi(0x1.23456789abcdefp+256, 0xffffffff);18 test__fixunstfsi(0x1.23456789abcdefp+256, 0xffffffff);
19 test__fixunstfsi(-0x1.23456789abcdefp+3, 0x0);19 test__fixunstfsi(-0x1.23456789abcdefp+3, 0x0);
std/special/compiler_rt/floatunsitf.zig+1-1
...@@ -17,7 +17,7 @@ pub extern fn __floatunsitf(a: u64) f128 {...@@ -17,7 +17,7 @@ pub extern fn __floatunsitf(a: u64) f128 {
17 const exp = (u64.bit_count - 1) - @clz(a);17 const exp = (u64.bit_count - 1) - @clz(a);
18 const shift = mantissa_bits - @intCast(u7, exp);18 const shift = mantissa_bits - @intCast(u7, exp);
1919
20 // TODO: @bitCast alignment error20 // TODO(#1148): @bitCast alignment error
21 var result align(16) = (@intCast(u128, a) << shift) ^ implicit_bit;21 var result align(16) = (@intCast(u128, a) << shift) ^ implicit_bit;
22 result += (@intCast(u128, exp) + exponent_bias) << mantissa_bits;22 result += (@intCast(u128, exp) + exponent_bias) << mantissa_bits;
2323
test/behavior.zig+1
...@@ -18,6 +18,7 @@ comptime {...@@ -18,6 +18,7 @@ comptime {
18 _ = @import("cases/cast.zig");18 _ = @import("cases/cast.zig");
19 _ = @import("cases/const_slice_child.zig");19 _ = @import("cases/const_slice_child.zig");
20 _ = @import("cases/coroutines.zig");20 _ = @import("cases/coroutines.zig");
21 _ = @import("cases/coroutine_await_struct.zig");
21 _ = @import("cases/defer.zig");22 _ = @import("cases/defer.zig");
22 _ = @import("cases/enum.zig");23 _ = @import("cases/enum.zig");
23 _ = @import("cases/enum_with_members.zig");24 _ = @import("cases/enum_with_members.zig");
test/cases/coroutine_await_struct.zig created+47
...@@ -0,0 +1,47 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const assert = std.debug.assert;
4
5const Foo = struct {
6 x: i32,
7};
8
9var await_a_promise: promise = undefined;
10var await_final_result = Foo{ .x = 0 };
11
12test "coroutine await struct" {
13 var da = std.heap.DirectAllocator.init();
14 defer da.deinit();
15
16 await_seq('a');
17 const p = async<&da.allocator> await_amain() catch unreachable;
18 await_seq('f');
19 resume await_a_promise;
20 await_seq('i');
21 assert(await_final_result.x == 1234);
22 assert(std.mem.eql(u8, await_points, "abcdefghi"));
23}
24async fn await_amain() void {
25 await_seq('b');
26 const p = async await_another() catch unreachable;
27 await_seq('e');
28 await_final_result = await p;
29 await_seq('h');
30}
31async fn await_another() Foo {
32 await_seq('c');
33 suspend |p| {
34 await_seq('d');
35 await_a_promise = p;
36 }
37 await_seq('g');
38 return Foo{ .x = 1234 };
39}
40
41var await_points = []u8{0} ** "abcdefghi".len;
42var await_seq_index: usize = 0;
43
44fn await_seq(c: u8) void {
45 await_points[await_seq_index] = c;
46 await_seq_index += 1;
47}
test/cases/coroutines.zig+2-2
...@@ -116,14 +116,14 @@ test "coroutine await early return" {...@@ -116,14 +116,14 @@ test "coroutine await early return" {
116 defer da.deinit();116 defer da.deinit();
117117
118 early_seq('a');118 early_seq('a');
119 const p = async<&da.allocator> early_amain() catch unreachable;119 const p = async<&da.allocator> early_amain() catch @panic("out of memory");
120 early_seq('f');120 early_seq('f');
121 assert(early_final_result == 1234);121 assert(early_final_result == 1234);
122 assert(std.mem.eql(u8, early_points, "abcdef"));122 assert(std.mem.eql(u8, early_points, "abcdef"));
123}123}
124async fn early_amain() void {124async fn early_amain() void {
125 early_seq('b');125 early_seq('b');
126 const p = async early_another() catch unreachable;126 const p = async early_another() catch @panic("out of memory");
127 early_seq('d');127 early_seq('d');
128 early_final_result = await p;128 early_final_result = await p;
129 early_seq('e');129 early_seq('e');