Platform details
- macOS (Apple Silicon)
- zig versions (behavior identical on all)
- 0.10.0 aarch64
- 0.11-dev824 aarch64
Problem
I wrote this code for basic composable iterators:
pub fn RangeIterator(comptime NumberType: type) type {
return struct {
const This = @This();
const Item = NumberType;
start: NumberType,
step: NumberType,
len: usize,
_index: usize = 0,
fn next(this: *This) !?Item {
if (this._index >= this.len) {
return null;
}
defer this._index += 1;
return this.start + (this.step * @intCast(NumberType, this._index));
}
};
}
test "range iterator" {
// these tests pass!
var iterator = RangeIterator(u32){.start = 1, .step = 3, .len = 5};
try std.testing.expectEqual(iterator.next(), 1);
try std.testing.expectEqual(iterator.next(), 4);
try std.testing.expectEqual(iterator.next(), 7);
try std.testing.expectEqual(iterator.next(), 10);
try std.testing.expectEqual(iterator.next(), 13);
try std.testing.expectEqual(iterator.next(), null);
}
// based on pattern used for BufferedWriter & bufferedWriter
// https://github.com/ziglang/zig/blob/master/lib/std/io/buffered_writer.zig
pub fn IterWhile(
comptime IteratorType: type,
comptime ItemType: type,
comptime include_last: bool,
) type {
return struct {
const This = @This();
const Item = ItemType;
iterator: IteratorType,
predicate: fn (ItemType) bool,
_is_spent: bool = false,
pub fn next(this: *This) ?ItemType {
if (this._is_spent) {
return null;
}
const result = try this.iterator.next();
if (result == null) {
return null;
}
if (!this.predicate(result)) {
this._is_spent = true;
if (!include_last) return null;
}
return result;
}
};
}
pub fn iterWhile(
iterator: anytype,
predicate: fn (anytype) bool,
comptime include_last: bool,
) IterWhile(
@TypeOf(iterator),
@typeInfo(predicate).Fn.args[0].arg_type,
include_last,
) {
return .{ .iterator = iterator, .predicate = predicate };
}
test "iter while" {
// these tests generate a compiler error :S
var range = RangeIterator(u32){.start = 1, .step = 3, .len = 5};
var iterator = iterWhile(range, TestUtils.isOneDigit, false);
try std.testing.expectEqual(iterator.next(), 1);
try std.testing.expectEqual(iterator.next(), 4);
try std.testing.expectEqual(iterator.next(), 7);
try std.testing.expectEqual(iterator.next(), null);
}
const TestUtils = struct {
fn isOneDigit(value: u32) bool {
return value < 10;
}
};
If I comment out the second test block "iter while"
, the tests pass. But if I leave them in, I get the following error:
thread 1531026 panic: zig compiler bug: GenericPoison
Unable to dump stack trace: debug info stripped
zsh: abort zig test src/utils/iterator.zig
Questions
- Any ideas on what the problem is with the code? Edit: Or is this an issue with the compiler?
debug info stripped
-> why is that happening? Aren't I running this in debug mode by not passing any of the release build flags?