mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
AstGen: add error for discard of unbounded counter
This commit is contained in:
parent
22965e6fcb
commit
bcb72401d3
6 changed files with 150 additions and 1 deletions
|
|
@ -6346,8 +6346,9 @@ fn forExpr(
|
||||||
const i = @intCast(u32, i_usize);
|
const i = @intCast(u32, i_usize);
|
||||||
const capture_is_ref = token_tags[capture_token] == .asterisk;
|
const capture_is_ref = token_tags[capture_token] == .asterisk;
|
||||||
const ident_tok = capture_token + @boolToInt(capture_is_ref);
|
const ident_tok = capture_token + @boolToInt(capture_is_ref);
|
||||||
|
const is_discard = mem.eql(u8, tree.tokenSlice(ident_tok), "_");
|
||||||
|
|
||||||
if (mem.eql(u8, tree.tokenSlice(ident_tok), "_") and capture_is_ref) {
|
if (is_discard and capture_is_ref) {
|
||||||
return astgen.failTok(capture_token, "pointer modifier invalid on discard", .{});
|
return astgen.failTok(capture_token, "pointer modifier invalid on discard", .{});
|
||||||
}
|
}
|
||||||
// Skip over the comma, and on to the next capture (or the ending pipe character).
|
// Skip over the comma, and on to the next capture (or the ending pipe character).
|
||||||
|
|
@ -6367,6 +6368,10 @@ fn forExpr(
|
||||||
else
|
else
|
||||||
.none;
|
.none;
|
||||||
|
|
||||||
|
if (end_val == .none and is_discard) {
|
||||||
|
return astgen.failTok(ident_tok, "discard of unbounded counter", .{});
|
||||||
|
}
|
||||||
|
|
||||||
const start_is_zero = nodeIsTriviallyZero(tree, start_node);
|
const start_is_zero = nodeIsTriviallyZero(tree, start_node);
|
||||||
const range_len = if (end_val == .none or start_is_zero)
|
const range_len = if (end_val == .none or start_is_zero)
|
||||||
end_val
|
end_val
|
||||||
|
|
|
||||||
|
|
@ -276,3 +276,103 @@ test "two counters" {
|
||||||
|
|
||||||
try expect(sum == 10);
|
try expect(sum == 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "1-based counter and ptr to array" {
|
||||||
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||||
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||||
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||||
|
|
||||||
|
var ok: usize = 0;
|
||||||
|
|
||||||
|
for (1..6, "hello") |i, b| {
|
||||||
|
if (i == 1) {
|
||||||
|
try expect(b == 'h');
|
||||||
|
ok += 1;
|
||||||
|
}
|
||||||
|
if (i == 2) {
|
||||||
|
try expect(b == 'e');
|
||||||
|
ok += 1;
|
||||||
|
}
|
||||||
|
if (i == 3) {
|
||||||
|
try expect(b == 'l');
|
||||||
|
ok += 1;
|
||||||
|
}
|
||||||
|
if (i == 4) {
|
||||||
|
try expect(b == 'l');
|
||||||
|
ok += 1;
|
||||||
|
}
|
||||||
|
if (i == 5) {
|
||||||
|
try expect(b == 'o');
|
||||||
|
ok += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try expect(ok == 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "slice and two counters, one is offset and one is runtime" {
|
||||||
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||||
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||||
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||||
|
|
||||||
|
const slice: []const u8 = "blah";
|
||||||
|
var start: usize = 0;
|
||||||
|
|
||||||
|
for (slice, start..4, 1..5) |a, b, c| {
|
||||||
|
if (a == 'b') {
|
||||||
|
try expect(b == 0);
|
||||||
|
try expect(c == 1);
|
||||||
|
}
|
||||||
|
if (a == 'l') {
|
||||||
|
try expect(b == 1);
|
||||||
|
try expect(c == 2);
|
||||||
|
}
|
||||||
|
if (a == 'a') {
|
||||||
|
try expect(b == 2);
|
||||||
|
try expect(c == 3);
|
||||||
|
}
|
||||||
|
if (a == 'h') {
|
||||||
|
try expect(b == 3);
|
||||||
|
try expect(c == 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "two slices, one captured by-ref" {
|
||||||
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||||
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||||
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||||
|
|
||||||
|
var buf: [10]u8 = undefined;
|
||||||
|
const slice1: []const u8 = "blah";
|
||||||
|
const slice2: []u8 = buf[0..4];
|
||||||
|
|
||||||
|
for (slice1, slice2) |a, *b| {
|
||||||
|
b.* = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
try expect(slice2[0] == 'b');
|
||||||
|
try expect(slice2[1] == 'l');
|
||||||
|
try expect(slice2[2] == 'a');
|
||||||
|
try expect(slice2[3] == 'h');
|
||||||
|
}
|
||||||
|
|
||||||
|
test "raw pointer and slice" {
|
||||||
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||||
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||||
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||||
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||||
|
|
||||||
|
var buf: [10]u8 = undefined;
|
||||||
|
const slice: []const u8 = "blah";
|
||||||
|
const ptr: [*]u8 = buf[0..4];
|
||||||
|
|
||||||
|
for (ptr, slice) |*a, b| {
|
||||||
|
a.* = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
try expect(buf[0] == 'b');
|
||||||
|
try expect(buf[1] == 'l');
|
||||||
|
try expect(buf[2] == 'a');
|
||||||
|
try expect(buf[3] == 'h');
|
||||||
|
}
|
||||||
|
|
|
||||||
10
test/cases/compile_errors/for_discard_unbounded.zig
Normal file
10
test/cases/compile_errors/for_discard_unbounded.zig
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
export fn a() void {
|
||||||
|
for (0..10, 10..) |i, _| {
|
||||||
|
_ = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// error
|
||||||
|
// backend=stage2
|
||||||
|
// target=native
|
||||||
|
//
|
||||||
|
// :2:27: error: discard of unbounded counter
|
||||||
11
test/cases/compile_errors/for_empty.zig
Normal file
11
test/cases/compile_errors/for_empty.zig
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
export fn b() void {
|
||||||
|
for () |i| {
|
||||||
|
_ = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// error
|
||||||
|
// backend=stage2
|
||||||
|
// target=native
|
||||||
|
//
|
||||||
|
// :2:10: error: expected expression, found ')'
|
||||||
12
test/cases/compile_errors/for_extra_capture.zig
Normal file
12
test/cases/compile_errors/for_extra_capture.zig
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
export fn b() void {
|
||||||
|
for (0..10) |i, j| {
|
||||||
|
_ = i; _ = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// error
|
||||||
|
// backend=stage2
|
||||||
|
// target=native
|
||||||
|
//
|
||||||
|
// :2:21: error: extra capture in for loop
|
||||||
|
// :2:21: note: run 'zig fmt' to upgrade your code automatically
|
||||||
11
test/cases/compile_errors/for_extra_condition.zig
Normal file
11
test/cases/compile_errors/for_extra_condition.zig
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
export fn a() void {
|
||||||
|
for (0..10, 10..20) |i| {
|
||||||
|
_ = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// error
|
||||||
|
// backend=stage2
|
||||||
|
// target=native
|
||||||
|
//
|
||||||
|
// :2:19: error: for input is not captured
|
||||||
Loading…
Add table
Reference in a new issue