Skip to content

Commit bc982e6

Browse files
mikdusanandrewrk
authored andcommitted
fix std.fmt to handle std.SegmentedList
- add guards for use of prealloc_exp in SegmentedList - define prealloc_exp even when invalid because std.fmt comptime triggers lazy-init - fix std.fmt to print arrays of length 0 as style "[0]<typename>" because "<typename>@address" is n/a without address
1 parent 8736a5b commit bc982e6

File tree

2 files changed

+21
-11
lines changed

2 files changed

+21
-11
lines changed

std/fmt.zig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,9 @@ pub fn formatType(
426426
if (info.child == u8) {
427427
return formatText(value, fmt, options, context, Errors, output);
428428
}
429+
if (value.len == 0) {
430+
return format(context, Errors, output, "[0]{}", @typeName(T.Child));
431+
}
429432
return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(&value));
430433
},
431434
.Fn => {

std/segmented_list.zig

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,19 @@ const Allocator = std.mem.Allocator;
7777
pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type {
7878
return struct {
7979
const Self = @This();
80-
const prealloc_exp = blk: {
81-
// we don't use the prealloc_exp constant when prealloc_item_count is 0.
82-
assert(prealloc_item_count != 0);
83-
assert(std.math.isPowerOfTwo(prealloc_item_count));
80+
const ShelfIndex = std.math.Log2Int(usize);
8481

85-
const value = std.math.log2_int(usize, prealloc_item_count);
86-
break :blk @typeOf(1)(value);
82+
const prealloc_exp: ShelfIndex = blk: {
83+
// we don't use the prealloc_exp constant when prealloc_item_count is 0
84+
// but lazy-init may still be triggered by other code so supply a value
85+
if (prealloc_item_count == 0) {
86+
break :blk 0;
87+
} else {
88+
assert(std.math.isPowerOfTwo(prealloc_item_count));
89+
const value = std.math.log2_int(usize, prealloc_item_count);
90+
break :blk value;
91+
}
8792
};
88-
const ShelfIndex = std.math.Log2Int(usize);
8993

9094
prealloc_segment: [prealloc_item_count]T,
9195
dynamic_segments: [][*]T,
@@ -157,11 +161,12 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
157161

158162
/// Grows or shrinks capacity to match usage.
159163
pub fn setCapacity(self: *Self, new_capacity: usize) !void {
160-
if (new_capacity <= usize(1) << (prealloc_exp + self.dynamic_segments.len)) {
161-
return self.shrinkCapacity(new_capacity);
162-
} else {
163-
return self.growCapacity(new_capacity);
164+
if (prealloc_item_count != 0) {
165+
if (new_capacity <= usize(1) << (prealloc_exp + @intCast(ShelfIndex, self.dynamic_segments.len))) {
166+
return self.shrinkCapacity(new_capacity);
167+
}
164168
}
169+
return self.growCapacity(new_capacity);
165170
}
166171

167172
/// Only grows capacity, or retains current capacity
@@ -399,4 +404,6 @@ fn testSegmentedList(comptime prealloc: usize, allocator: *Allocator) !void {
399404
testing.expect(item == i);
400405
list.shrinkCapacity(list.len);
401406
}
407+
408+
try list.setCapacity(0);
402409
}

0 commit comments

Comments
 (0)