authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-02-18 18:56:37-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-02-18 19:20:19-07:00
log40c4c25e2b5e2242c3180cd8564dc22697bf363f
tree1afd7f26c0fa5b0b8bb170c3d4520895fe64d0a3
parent12a7a0d76f9435c8c538f762daa79a49ca0470af

Sema: add missing coercion when checking for loop len


2 files changed, 64 insertions(+), 1 deletions(-)

src/Sema.zig+2-1
...@@ -3934,12 +3934,13 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -3934,12 +3934,13 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
3934 .for_node_offset = inst_data.src_node,3934 .for_node_offset = inst_data.src_node,
3935 .input_index = i,3935 .input_index = i,
3936 } };3936 } };
3937 const arg_len = if (is_int) object else l: {3937 const arg_len_uncoerced = if (is_int) object else l: {
3938 try checkIndexable(sema, block, arg_src, object_ty);3938 try checkIndexable(sema, block, arg_src, object_ty);
3939 if (!object_ty.indexableHasLen()) continue;3939 if (!object_ty.indexableHasLen()) continue;
39403940
3941 break :l try sema.fieldVal(block, arg_src, object, "len", arg_src);3941 break :l try sema.fieldVal(block, arg_src, object, "len", arg_src);
3942 };3942 };
3943 const arg_len = try sema.coerce(block, Type.usize, arg_len_uncoerced, arg_src);
3943 if (len == .none) {3944 if (len == .none) {
3944 len = arg_len;3945 len = arg_len;
3945 len_idx = i;3946 len_idx = i;
test/behavior/for.zig+62
...@@ -397,3 +397,65 @@ test "raw pointer and counter" {...@@ -397,3 +397,65 @@ test "raw pointer and counter" {
397 try expect(buf[2] == 'C');397 try expect(buf[2] == 'C');
398 try expect(buf[3] == 'D');398 try expect(buf[3] == 'D');
399}399}
400
401test "inline for with slice as the comptime-known" {
402 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
403 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
404 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
405 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
406
407 const comptime_slice = "hello";
408 var runtime_i: usize = 3;
409
410 const S = struct {
411 var ok: usize = 0;
412 fn check(comptime a: u8, b: usize) !void {
413 if (a == 'l') {
414 try expect(b == 3);
415 ok += 1;
416 } else if (a == 'o') {
417 try expect(b == 4);
418 ok += 1;
419 } else {
420 @compileError("fail");
421 }
422 }
423 };
424
425 inline for (comptime_slice[3..5], runtime_i..5) |a, b| {
426 try S.check(a, b);
427 }
428
429 try expect(S.ok == 2);
430}
431
432test "inline for with counter as the comptime-known" {
433 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
434 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
435 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
436 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
437
438 var runtime_slice = "hello";
439 var runtime_i: usize = 3;
440
441 const S = struct {
442 var ok: usize = 0;
443 fn check(a: u8, comptime b: usize) !void {
444 if (b == 3) {
445 try expect(a == 'l');
446 ok += 1;
447 } else if (b == 4) {
448 try expect(a == 'o');
449 ok += 1;
450 } else {
451 @compileError("fail");
452 }
453 }
454 };
455
456 inline for (runtime_slice[runtime_i..5], 3..5) |a, b| {
457 try S.check(a, b);
458 }
459
460 try expect(S.ok == 2);
461}