Merge pull request #4868 from xackus/new-arraylist-api

new ArrayList API
This commit is contained in:
Andrew Kelley 2020-04-03 22:31:15 -04:00 committed by GitHub
commit e89c42655c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 185 additions and 161 deletions

View File

@ -20,11 +20,9 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
return struct { return struct {
const Self = @This(); const Self = @This();
/// Use `span` instead of slicing this directly, because if you don't /// Content of the ArrayList
/// specify the end position of the slice, this will potentially give
/// you uninitialized memory.
items: Slice, items: Slice,
len: usize, capacity: usize,
allocator: *Allocator, allocator: *Allocator,
pub const Slice = if (alignment) |a| ([]align(a) T) else []T; pub const Slice = if (alignment) |a| ([]align(a) T) else []T;
@ -34,7 +32,7 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
pub fn init(allocator: *Allocator) Self { pub fn init(allocator: *Allocator) Self {
return Self{ return Self{
.items = &[_]T{}, .items = &[_]T{},
.len = 0, .capacity = 0,
.allocator = allocator, .allocator = allocator,
}; };
} }
@ -49,60 +47,55 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
/// Release all allocated memory. /// Release all allocated memory.
pub fn deinit(self: Self) void { pub fn deinit(self: Self) void {
self.allocator.free(self.items); self.allocator.free(self.allocatedSlice());
} }
/// Deprecated: use `items` field directly.
/// Return contents as a slice. Only valid while the list /// Return contents as a slice. Only valid while the list
/// doesn't change size. /// doesn't change size.
pub fn span(self: var) @TypeOf(self.items[0..self.len]) { pub fn span(self: var) @TypeOf(self.items) {
return self.items[0..self.len]; return self.items;
} }
/// Deprecated: use `span`. /// Deprecated: use `items` field directly.
pub fn toSlice(self: Self) Slice { pub fn toSlice(self: Self) Slice {
return self.span(); return self.items;
} }
/// Deprecated: use `span`. /// Deprecated: use `items` field directly.
pub fn toSliceConst(self: Self) SliceConst { pub fn toSliceConst(self: Self) SliceConst {
return self.span(); return self.items;
} }
/// Deprecated: use `span()[i]`. /// Deprecated: use `list.items[i]`.
pub fn at(self: Self, i: usize) T { pub fn at(self: Self, i: usize) T {
return self.span()[i]; return self.items[i];
} }
/// Deprecated: use `&span()[i]`. /// Deprecated: use `&list.items[i]`.
pub fn ptrAt(self: Self, i: usize) *T { pub fn ptrAt(self: Self, i: usize) *T {
return &self.span()[i]; return &self.items[i];
} }
/// Deprecated: use `if (i >= list.len) return error.OutOfBounds else span()[i] = item`. /// Deprecated: use `if (i >= list.items.len) return error.OutOfBounds else list.items[i] = item`.
pub fn setOrError(self: Self, i: usize, item: T) !void { pub fn setOrError(self: Self, i: usize, item: T) !void {
if (i >= self.len) return error.OutOfBounds; if (i >= self.items.len) return error.OutOfBounds;
self.items[i] = item; self.items[i] = item;
} }
/// Deprecated: use `list.span()[i] = item`. /// Deprecated: use `list.items[i] = item`.
pub fn set(self: *Self, i: usize, item: T) void { pub fn set(self: *Self, i: usize, item: T) void {
assert(i < self.len); assert(i < self.items.len);
self.items[i] = item; self.items[i] = item;
} }
/// Return the maximum number of items the list can hold
/// without allocating more memory.
pub fn capacity(self: Self) usize {
return self.items.len;
}
/// ArrayList takes ownership of the passed in slice. The slice must have been /// ArrayList takes ownership of the passed in slice. The slice must have been
/// allocated with `allocator`. /// allocated with `allocator`.
/// Deinitialize with `deinit` or use `toOwnedSlice`. /// Deinitialize with `deinit` or use `toOwnedSlice`.
pub fn fromOwnedSlice(allocator: *Allocator, slice: Slice) Self { pub fn fromOwnedSlice(allocator: *Allocator, slice: Slice) Self {
return Self{ return Self{
.items = slice, .items = slice,
.len = slice.len, .capacity = slice.len,
.allocator = allocator, .allocator = allocator,
}; };
} }
@ -110,7 +103,7 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
/// The caller owns the returned memory. ArrayList becomes empty. /// The caller owns the returned memory. ArrayList becomes empty.
pub fn toOwnedSlice(self: *Self) Slice { pub fn toOwnedSlice(self: *Self) Slice {
const allocator = self.allocator; const allocator = self.allocator;
const result = allocator.shrink(self.items, self.len); const result = allocator.shrink(self.allocatedSlice(), self.items.len);
self.* = init(allocator); self.* = init(allocator);
return result; return result;
} }
@ -118,10 +111,10 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
/// Insert `item` at index `n`. Moves `list[n .. list.len]` /// Insert `item` at index `n`. Moves `list[n .. list.len]`
/// to make room. /// to make room.
pub fn insert(self: *Self, n: usize, item: T) !void { pub fn insert(self: *Self, n: usize, item: T) !void {
try self.ensureCapacity(self.len + 1); try self.ensureCapacity(self.items.len + 1);
self.len += 1; self.items.len += 1;
mem.copyBackwards(T, self.items[n + 1 .. self.len], self.items[n .. self.len - 1]); mem.copyBackwards(T, self.items[n + 1 .. self.items.len], self.items[n .. self.items.len - 1]);
self.items[n] = item; self.items[n] = item;
} }
@ -129,10 +122,10 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
/// `list[i .. list.len]` to make room. /// `list[i .. list.len]` to make room.
/// This operation is O(N). /// This operation is O(N).
pub fn insertSlice(self: *Self, i: usize, items: SliceConst) !void { pub fn insertSlice(self: *Self, i: usize, items: SliceConst) !void {
try self.ensureCapacity(self.len + items.len); try self.ensureCapacity(self.items.len + items.len);
self.len += items.len; self.items.len += items.len;
mem.copyBackwards(T, self.items[i + items.len .. self.len], self.items[i .. self.len - items.len]); mem.copyBackwards(T, self.items[i + items.len .. self.items.len], self.items[i .. self.items.len - items.len]);
mem.copy(T, self.items[i .. i + items.len], items); mem.copy(T, self.items[i .. i + items.len], items);
} }
@ -153,13 +146,13 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
/// Asserts the array has at least one item. /// Asserts the array has at least one item.
/// This operation is O(N). /// This operation is O(N).
pub fn orderedRemove(self: *Self, i: usize) T { pub fn orderedRemove(self: *Self, i: usize) T {
const newlen = self.len - 1; const newlen = self.items.len - 1;
if (newlen == i) return self.pop(); if (newlen == i) return self.pop();
const old_item = self.at(i); const old_item = self.items[i];
for (self.items[i..newlen]) |*b, j| b.* = self.items[i + 1 + j]; for (self.items[i..newlen]) |*b, j| b.* = self.items[i + 1 + j];
self.items[newlen] = undefined; self.items[newlen] = undefined;
self.len = newlen; self.items.len = newlen;
return old_item; return old_item;
} }
@ -167,26 +160,28 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
/// The empty slot is filled from the end of the list. /// The empty slot is filled from the end of the list.
/// This operation is O(1). /// This operation is O(1).
pub fn swapRemove(self: *Self, i: usize) T { pub fn swapRemove(self: *Self, i: usize) T {
if (self.len - 1 == i) return self.pop(); if (self.items.len - 1 == i) return self.pop();
const slice = self.span(); const old_item = self.items[i];
const old_item = slice[i]; self.items[i] = self.pop();
slice[i] = self.pop();
return old_item; return old_item;
} }
/// Deprecated: use `if (i >= list.len) return error.OutOfBounds else list.swapRemove(i)`. /// Deprecated: use `if (i >= list.items.len) return error.OutOfBounds else list.swapRemove(i)`.
pub fn swapRemoveOrError(self: *Self, i: usize) !T { pub fn swapRemoveOrError(self: *Self, i: usize) !T {
if (i >= self.len) return error.OutOfBounds; if (i >= self.items.len) return error.OutOfBounds;
return self.swapRemove(i); return self.swapRemove(i);
} }
/// Append the slice of items to the list. Allocates more /// Append the slice of items to the list. Allocates more
/// memory as necessary. /// memory as necessary.
pub fn appendSlice(self: *Self, items: SliceConst) !void { pub fn appendSlice(self: *Self, items: SliceConst) !void {
try self.ensureCapacity(self.len + items.len); const oldlen = self.items.len;
mem.copy(T, self.items[self.len..], items); const newlen = self.items.len + items.len;
self.len += items.len;
try self.ensureCapacity(newlen);
self.items.len = newlen;
mem.copy(T, self.items[oldlen..], items);
} }
/// Same as `append` except it returns the number of bytes written, which is always the same /// Same as `append` except it returns the number of bytes written, which is always the same
@ -206,50 +201,58 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
/// Append a value to the list `n` times. /// Append a value to the list `n` times.
/// Allocates more memory as necessary. /// Allocates more memory as necessary.
pub fn appendNTimes(self: *Self, value: T, n: usize) !void { pub fn appendNTimes(self: *Self, value: T, n: usize) !void {
const old_len = self.len; const old_len = self.items.len;
try self.resize(self.len + n); try self.resize(self.items.len + n);
mem.set(T, self.items[old_len..self.len], value); mem.set(T, self.items[old_len..self.items.len], value);
} }
/// Adjust the list's length to `new_len`. /// Adjust the list's length to `new_len`.
/// Does not initialize added items if any. /// Does not initialize added items if any.
pub fn resize(self: *Self, new_len: usize) !void { pub fn resize(self: *Self, new_len: usize) !void {
try self.ensureCapacity(new_len); try self.ensureCapacity(new_len);
self.len = new_len; self.items.len = new_len;
} }
/// Reduce allocated capacity to `new_len`. /// Reduce allocated capacity to `new_len`.
/// Invalidates element pointers. /// Invalidates element pointers.
pub fn shrink(self: *Self, new_len: usize) void { pub fn shrink(self: *Self, new_len: usize) void {
assert(new_len <= self.len); assert(new_len <= self.items.len);
self.len = new_len;
self.items = self.allocator.realloc(self.items, new_len) catch |e| switch (e) { self.items = self.allocator.realloc(self.allocatedSlice(), new_len) catch |e| switch (e) {
error.OutOfMemory => return, // no problem, capacity is still correct then. error.OutOfMemory => { // no problem, capacity is still correct then.
self.items.len = new_len;
return;
},
}; };
self.capacity = new_len;
} }
pub fn ensureCapacity(self: *Self, new_capacity: usize) !void { pub fn ensureCapacity(self: *Self, new_capacity: usize) !void {
var better_capacity = self.capacity(); var better_capacity = self.capacity;
if (better_capacity >= new_capacity) return; if (better_capacity >= new_capacity) return;
while (true) { while (true) {
better_capacity += better_capacity / 2 + 8; better_capacity += better_capacity / 2 + 8;
if (better_capacity >= new_capacity) break; if (better_capacity >= new_capacity) break;
} }
self.items = try self.allocator.realloc(self.items, better_capacity);
const new_memory = try self.allocator.realloc(self.allocatedSlice(), better_capacity);
self.items.ptr = new_memory.ptr;
self.capacity = new_memory.len;
} }
/// Increases the array's length to match the full capacity that is already allocated. /// Increases the array's length to match the full capacity that is already allocated.
/// The new elements have `undefined` values. This operation does not invalidate any /// The new elements have `undefined` values. This operation does not invalidate any
/// element pointers. /// element pointers.
pub fn expandToCapacity(self: *Self) void { pub fn expandToCapacity(self: *Self) void {
self.len = self.items.len; self.items.len = self.capacity;
} }
/// Increase length by 1, returning pointer to the new item. /// Increase length by 1, returning pointer to the new item.
/// The returned pointer becomes invalid when the list is resized. /// The returned pointer becomes invalid when the list is resized.
pub fn addOne(self: *Self) !*T { pub fn addOne(self: *Self) !*T {
const new_length = self.len + 1; const newlen = self.items.len + 1;
try self.ensureCapacity(new_length); try self.ensureCapacity(newlen);
return self.addOneAssumeCapacity(); return self.addOneAssumeCapacity();
} }
@ -257,25 +260,32 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
/// Asserts that there is already space for the new item without allocating more. /// Asserts that there is already space for the new item without allocating more.
/// The returned pointer becomes invalid when the list is resized. /// The returned pointer becomes invalid when the list is resized.
pub fn addOneAssumeCapacity(self: *Self) *T { pub fn addOneAssumeCapacity(self: *Self) *T {
assert(self.len < self.capacity()); assert(self.items.len < self.capacity);
const result = &self.items[self.len];
self.len += 1; self.items.len += 1;
return result; return &self.items[self.items.len - 1];
} }
/// Remove and return the last element from the list. /// Remove and return the last element from the list.
/// Asserts the list has at least one item. /// Asserts the list has at least one item.
pub fn pop(self: *Self) T { pub fn pop(self: *Self) T {
self.len -= 1; const val = self.items[self.items.len - 1];
return self.items[self.len]; self.items.len -= 1;
return val;
} }
/// Remove and return the last element from the list. /// Remove and return the last element from the list.
/// If the list is empty, returns `null`. /// If the list is empty, returns `null`.
pub fn popOrNull(self: *Self) ?T { pub fn popOrNull(self: *Self) ?T {
if (self.len == 0) return null; if (self.items.len == 0) return null;
return self.pop(); return self.pop();
} }
// For a nicer API, `items.len` is the length, not the capacity.
// This requires "unsafe" slicing.
fn allocatedSlice(self: Self) Slice {
return self.items.ptr[0..self.capacity];
}
}; };
} }
@ -283,15 +293,15 @@ test "std.ArrayList.init" {
var list = ArrayList(i32).init(testing.allocator); var list = ArrayList(i32).init(testing.allocator);
defer list.deinit(); defer list.deinit();
testing.expect(list.len == 0); testing.expect(list.items.len == 0);
testing.expect(list.capacity() == 0); testing.expect(list.capacity == 0);
} }
test "std.ArrayList.initCapacity" { test "std.ArrayList.initCapacity" {
var list = try ArrayList(i8).initCapacity(testing.allocator, 200); var list = try ArrayList(i8).initCapacity(testing.allocator, 200);
defer list.deinit(); defer list.deinit();
testing.expect(list.len == 0); testing.expect(list.items.len == 0);
testing.expect(list.capacity() >= 200); testing.expect(list.capacity >= 200);
} }
test "std.ArrayList.basic" { test "std.ArrayList.basic" {
@ -315,7 +325,7 @@ test "std.ArrayList.basic" {
} }
} }
for (list.span()) |v, i| { for (list.items) |v, i| {
testing.expect(v == @intCast(i32, i + 1)); testing.expect(v == @intCast(i32, i + 1));
} }
@ -324,19 +334,19 @@ test "std.ArrayList.basic" {
} }
testing.expect(list.pop() == 10); testing.expect(list.pop() == 10);
testing.expect(list.len == 9); testing.expect(list.items.len == 9);
list.appendSlice(&[_]i32{ 1, 2, 3 }) catch unreachable; list.appendSlice(&[_]i32{ 1, 2, 3 }) catch unreachable;
testing.expect(list.len == 12); testing.expect(list.items.len == 12);
testing.expect(list.pop() == 3); testing.expect(list.pop() == 3);
testing.expect(list.pop() == 2); testing.expect(list.pop() == 2);
testing.expect(list.pop() == 1); testing.expect(list.pop() == 1);
testing.expect(list.len == 9); testing.expect(list.items.len == 9);
list.appendSlice(&[_]i32{}) catch unreachable; list.appendSlice(&[_]i32{}) catch unreachable;
testing.expect(list.len == 9); testing.expect(list.items.len == 9);
// can only set on indices < self.len // can only set on indices < self.items.len
list.set(7, 33); list.set(7, 33);
list.set(8, 42); list.set(8, 42);
@ -352,8 +362,8 @@ test "std.ArrayList.appendNTimes" {
defer list.deinit(); defer list.deinit();
try list.appendNTimes(2, 10); try list.appendNTimes(2, 10);
testing.expectEqual(@as(usize, 10), list.len); testing.expectEqual(@as(usize, 10), list.items.len);
for (list.span()) |element| { for (list.items) |element| {
testing.expectEqual(@as(i32, 2), element); testing.expectEqual(@as(i32, 2), element);
} }
} }
@ -378,17 +388,17 @@ test "std.ArrayList.orderedRemove" {
//remove from middle //remove from middle
testing.expectEqual(@as(i32, 4), list.orderedRemove(3)); testing.expectEqual(@as(i32, 4), list.orderedRemove(3));
testing.expectEqual(@as(i32, 5), list.at(3)); testing.expectEqual(@as(i32, 5), list.items[3]);
testing.expectEqual(@as(usize, 6), list.len); testing.expectEqual(@as(usize, 6), list.items.len);
//remove from end //remove from end
testing.expectEqual(@as(i32, 7), list.orderedRemove(5)); testing.expectEqual(@as(i32, 7), list.orderedRemove(5));
testing.expectEqual(@as(usize, 5), list.len); testing.expectEqual(@as(usize, 5), list.items.len);
//remove from front //remove from front
testing.expectEqual(@as(i32, 1), list.orderedRemove(0)); testing.expectEqual(@as(i32, 1), list.orderedRemove(0));
testing.expectEqual(@as(i32, 2), list.at(0)); testing.expectEqual(@as(i32, 2), list.items[0]);
testing.expectEqual(@as(usize, 4), list.len); testing.expectEqual(@as(usize, 4), list.items.len);
} }
test "std.ArrayList.swapRemove" { test "std.ArrayList.swapRemove" {
@ -405,17 +415,17 @@ test "std.ArrayList.swapRemove" {
//remove from middle //remove from middle
testing.expect(list.swapRemove(3) == 4); testing.expect(list.swapRemove(3) == 4);
testing.expect(list.at(3) == 7); testing.expect(list.items[3] == 7);
testing.expect(list.len == 6); testing.expect(list.items.len == 6);
//remove from end //remove from end
testing.expect(list.swapRemove(5) == 6); testing.expect(list.swapRemove(5) == 6);
testing.expect(list.len == 5); testing.expect(list.items.len == 5);
//remove from front //remove from front
testing.expect(list.swapRemove(0) == 1); testing.expect(list.swapRemove(0) == 1);
testing.expect(list.at(0) == 5); testing.expect(list.items[0] == 5);
testing.expect(list.len == 4); testing.expect(list.items.len == 4);
} }
test "std.ArrayList.swapRemoveOrError" { test "std.ArrayList.swapRemoveOrError" {
@ -478,7 +488,7 @@ test "std.ArrayList.insertSlice" {
const items = [_]i32{1}; const items = [_]i32{1};
try list.insertSlice(0, items[0..0]); try list.insertSlice(0, items[0..0]);
testing.expect(list.len == 6); testing.expect(list.items.len == 6);
testing.expect(list.items[0] == 1); testing.expect(list.items[0] == 1);
} }
@ -504,3 +514,18 @@ test "std.ArrayList(u8) implements outStream" {
testing.expectEqualSlices(u8, "x: 42\ny: 1234\n", buffer.span()); testing.expectEqualSlices(u8, "x: 42\ny: 1234\n", buffer.span());
} }
test "std.ArrayList.shrink still sets length on error.OutOfMemory" {
// use an arena allocator to make sure realloc returns error.OutOfMemory
var arena = std.heap.ArenaAllocator.init(testing.allocator);
defer arena.deinit();
var list = ArrayList(i32).init(&arena.allocator);
try list.append(1);
try list.append(2);
try list.append(3);
list.shrink(1);
testing.expect(list.items.len == 1);
}

View File

@ -82,8 +82,8 @@ pub fn ArrayListSentineled(comptime T: type, comptime sentinel: T) type {
self.list.deinit(); self.list.deinit();
} }
pub fn span(self: var) @TypeOf(self.list.items[0 .. self.list.len - 1 :sentinel]) { pub fn span(self: var) @TypeOf(self.list.items[0..:sentinel]) {
return self.list.span()[0..self.len() :sentinel]; return self.list.items[0..self.len() :sentinel];
} }
pub fn shrink(self: *Self, new_len: usize) void { pub fn shrink(self: *Self, new_len: usize) void {
@ -98,16 +98,16 @@ pub fn ArrayListSentineled(comptime T: type, comptime sentinel: T) type {
} }
pub fn isNull(self: Self) bool { pub fn isNull(self: Self) bool {
return self.list.len == 0; return self.list.items.len == 0;
} }
pub fn len(self: Self) usize { pub fn len(self: Self) usize {
return self.list.len - 1; return self.list.items.len - 1;
} }
pub fn capacity(self: Self) usize { pub fn capacity(self: Self) usize {
return if (self.list.items.len > 0) return if (self.list.capacity > 0)
self.list.items.len - 1 self.list.capacity - 1
else else
0; 0;
} }
@ -115,13 +115,13 @@ pub fn ArrayListSentineled(comptime T: type, comptime sentinel: T) type {
pub fn appendSlice(self: *Self, m: []const T) !void { pub fn appendSlice(self: *Self, m: []const T) !void {
const old_len = self.len(); const old_len = self.len();
try self.resize(old_len + m.len); try self.resize(old_len + m.len);
mem.copy(T, self.list.span()[old_len..], m); mem.copy(T, self.list.items[old_len..], m);
} }
pub fn append(self: *Self, byte: T) !void { pub fn append(self: *Self, byte: T) !void {
const old_len = self.len(); const old_len = self.len();
try self.resize(old_len + 1); try self.resize(old_len + 1);
self.list.span()[old_len] = byte; self.list.items[old_len] = byte;
} }
pub fn eql(self: Self, m: []const T) bool { pub fn eql(self: Self, m: []const T) bool {

View File

@ -1779,7 +1779,7 @@ pub const LibExeObjStep = struct {
const self = @fieldParentPtr(LibExeObjStep, "step", step); const self = @fieldParentPtr(LibExeObjStep, "step", step);
const builder = self.builder; const builder = self.builder;
if (self.root_src == null and self.link_objects.len == 0) { if (self.root_src == null and self.link_objects.items.len == 0) {
warn("{}: linker needs 1 or more objects to link\n", .{self.step.name}); warn("{}: linker needs 1 or more objects to link\n", .{self.step.name});
return error.NeedAnObject; return error.NeedAnObject;
} }
@ -1847,7 +1847,7 @@ pub const LibExeObjStep = struct {
} }
} }
if (self.build_options_contents.len > 0) { if (self.build_options_contents.items.len > 0) {
const build_options_file = try fs.path.join( const build_options_file = try fs.path.join(
builder.allocator, builder.allocator,
&[_][]const u8{ builder.cache_root, builder.fmt("{}_build_options.zig", .{self.name}) }, &[_][]const u8{ builder.cache_root, builder.fmt("{}_build_options.zig", .{self.name}) },

View File

@ -94,7 +94,7 @@ const BinaryElfOutput = struct {
sort.sort(*BinaryElfSegment, self.segments.span(), segmentSortCompare); sort.sort(*BinaryElfSegment, self.segments.span(), segmentSortCompare);
if (self.segments.len > 0) { if (self.segments.items.len > 0) {
const firstSegment = self.segments.at(0); const firstSegment = self.segments.at(0);
if (firstSegment.firstSection) |firstSection| { if (firstSegment.firstSection) |firstSection| {
const diff = firstSection.elfOffset - firstSegment.elfOffset; const diff = firstSection.elfOffset - firstSegment.elfOffset;

View File

@ -181,7 +181,7 @@ pub const Coff = struct {
} }
pub fn loadSections(self: *Coff) !void { pub fn loadSections(self: *Coff) !void {
if (self.sections.len == self.coff_header.number_of_sections) if (self.sections.items.len == self.coff_header.number_of_sections)
return; return;
try self.sections.ensureCapacity(self.coff_header.number_of_sections); try self.sections.ensureCapacity(self.coff_header.number_of_sections);

View File

@ -1478,7 +1478,7 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {
var coff_section: *coff.Section = undefined; var coff_section: *coff.Section = undefined;
const mod_index = for (self.sect_contribs) |sect_contrib| { const mod_index = for (self.sect_contribs) |sect_contrib| {
if (sect_contrib.Section > self.coff.sections.len) continue; if (sect_contrib.Section > self.coff.sections.items.len) continue;
// Remember that SectionContribEntry.Section is 1-based. // Remember that SectionContribEntry.Section is 1-based.
coff_section = &self.coff.sections.span()[sect_contrib.Section - 1]; coff_section = &self.coff.sections.span()[sect_contrib.Section - 1];

View File

@ -206,7 +206,7 @@ const LineNumberProgram = struct {
if (self.target_address >= self.prev_address and self.target_address < self.address) { if (self.target_address >= self.prev_address and self.target_address < self.address) {
const file_entry = if (self.prev_file == 0) { const file_entry = if (self.prev_file == 0) {
return error.MissingDebugInfo; return error.MissingDebugInfo;
} else if (self.prev_file - 1 >= self.file_entries.len) { } else if (self.prev_file - 1 >= self.file_entries.items.len) {
return error.InvalidDebugInfo; return error.InvalidDebugInfo;
} else } else
&self.file_entries.items[self.prev_file - 1]; &self.file_entries.items[self.prev_file - 1];
@ -645,7 +645,7 @@ pub const DwarfInfo = struct {
.offset = abbrev_offset, .offset = abbrev_offset,
.table = try di.parseAbbrevTable(abbrev_offset), .table = try di.parseAbbrevTable(abbrev_offset),
}); });
return &di.abbrev_table_list.items[di.abbrev_table_list.len - 1].table; return &di.abbrev_table_list.items[di.abbrev_table_list.items.len - 1].table;
} }
fn parseAbbrevTable(di: *DwarfInfo, offset: u64) !AbbrevTable { fn parseAbbrevTable(di: *DwarfInfo, offset: u64) !AbbrevTable {
@ -665,7 +665,7 @@ pub const DwarfInfo = struct {
.has_children = (try in.readByte()) == CHILDREN_yes, .has_children = (try in.readByte()) == CHILDREN_yes,
.attrs = ArrayList(AbbrevAttr).init(di.allocator()), .attrs = ArrayList(AbbrevAttr).init(di.allocator()),
}); });
const attrs = &result.items[result.len - 1].attrs; const attrs = &result.items[result.items.len - 1].attrs;
while (true) { while (true) {
const attr_id = try leb.readULEB128(u64, in); const attr_id = try leb.readULEB128(u64, in);
@ -689,7 +689,7 @@ pub const DwarfInfo = struct {
.has_children = table_entry.has_children, .has_children = table_entry.has_children,
.attrs = ArrayList(Die.Attr).init(di.allocator()), .attrs = ArrayList(Die.Attr).init(di.allocator()),
}; };
try result.attrs.resize(table_entry.attrs.len); try result.attrs.resize(table_entry.attrs.items.len);
for (table_entry.attrs.span()) |attr, i| { for (table_entry.attrs.span()) |attr, i| {
result.attrs.items[i] = Die.Attr{ result.attrs.items[i] = Die.Attr{
.id = attr.attr_id, .id = attr.attr_id,

View File

@ -1440,9 +1440,9 @@ pub const Walker = struct {
/// a reference to the path. /// a reference to the path.
pub fn next(self: *Walker) !?Entry { pub fn next(self: *Walker) !?Entry {
while (true) { while (true) {
if (self.stack.len == 0) return null; if (self.stack.items.len == 0) return null;
// `top` becomes invalid after appending to `self.stack`. // `top` becomes invalid after appending to `self.stack`.
const top = &self.stack.span()[self.stack.len - 1]; const top = &self.stack.span()[self.stack.items.len - 1];
const dirname_len = top.dirname_len; const dirname_len = top.dirname_len;
if (try top.dir_it.next()) |base| { if (try top.dir_it.next()) |base| {
self.name_buffer.shrink(dirname_len); self.name_buffer.shrink(dirname_len);
@ -1457,7 +1457,7 @@ pub const Walker = struct {
errdefer new_dir.close(); errdefer new_dir.close();
try self.stack.append(StackItem{ try self.stack.append(StackItem{
.dir_it = new_dir.iterate(), .dir_it = new_dir.iterate(),
.dirname_len = self.name_buffer.len, .dirname_len = self.name_buffer.items.len,
}); });
} }
} }

View File

@ -139,7 +139,7 @@ pub const Headers = struct {
pub fn clone(self: Self, allocator: *Allocator) !Self { pub fn clone(self: Self, allocator: *Allocator) !Self {
var other = Headers.init(allocator); var other = Headers.init(allocator);
errdefer other.deinit(); errdefer other.deinit();
try other.data.ensureCapacity(self.data.len); try other.data.ensureCapacity(self.data.items.len);
try other.index.initCapacity(self.index.entries.len); try other.index.initCapacity(self.index.entries.len);
for (self.data.span()) |entry| { for (self.data.span()) |entry| {
try other.append(entry.name, entry.value, entry.never_index); try other.append(entry.name, entry.value, entry.never_index);
@ -152,7 +152,7 @@ pub const Headers = struct {
} }
pub fn append(self: *Self, name: []const u8, value: []const u8, never_index: ?bool) !void { pub fn append(self: *Self, name: []const u8, value: []const u8, never_index: ?bool) !void {
const n = self.data.len + 1; const n = self.data.items.len + 1;
try self.data.ensureCapacity(n); try self.data.ensureCapacity(n);
var entry: HeaderEntry = undefined; var entry: HeaderEntry = undefined;
if (self.index.get(name)) |kv| { if (self.index.get(name)) |kv| {
@ -197,7 +197,7 @@ pub const Headers = struct {
if (self.index.remove(name)) |kv| { if (self.index.remove(name)) |kv| {
var dex = &kv.value; var dex = &kv.value;
// iterate backwards // iterate backwards
var i = dex.len; var i = dex.items.len;
while (i > 0) { while (i > 0) {
i -= 1; i -= 1;
const data_index = dex.at(i); const data_index = dex.at(i);
@ -220,18 +220,18 @@ pub const Headers = struct {
const removed = self.data.orderedRemove(i); const removed = self.data.orderedRemove(i);
const kv = self.index.get(removed.name).?; const kv = self.index.get(removed.name).?;
var dex = &kv.value; var dex = &kv.value;
if (dex.len == 1) { if (dex.items.len == 1) {
// was last item; delete the index // was last item; delete the index
_ = self.index.remove(kv.key); _ = self.index.remove(kv.key);
dex.deinit(); dex.deinit();
removed.deinit(); removed.deinit();
self.allocator.free(kv.key); self.allocator.free(kv.key);
} else { } else {
dex.shrink(dex.len - 1); dex.shrink(dex.items.len - 1);
removed.deinit(); removed.deinit();
} }
// if it was the last item; no need to rebuild index // if it was the last item; no need to rebuild index
if (i != self.data.len) { if (i != self.data.items.len) {
self.rebuild_index(); self.rebuild_index();
} }
} }
@ -242,18 +242,18 @@ pub const Headers = struct {
const removed = self.data.swapRemove(i); const removed = self.data.swapRemove(i);
const kv = self.index.get(removed.name).?; const kv = self.index.get(removed.name).?;
var dex = &kv.value; var dex = &kv.value;
if (dex.len == 1) { if (dex.items.len == 1) {
// was last item; delete the index // was last item; delete the index
_ = self.index.remove(kv.key); _ = self.index.remove(kv.key);
dex.deinit(); dex.deinit();
removed.deinit(); removed.deinit();
self.allocator.free(kv.key); self.allocator.free(kv.key);
} else { } else {
dex.shrink(dex.len - 1); dex.shrink(dex.items.len - 1);
removed.deinit(); removed.deinit();
} }
// if it was the last item; no need to rebuild index // if it was the last item; no need to rebuild index
if (i != self.data.len) { if (i != self.data.items.len) {
self.rebuild_index(); self.rebuild_index();
} }
} }
@ -277,7 +277,7 @@ pub const Headers = struct {
pub fn get(self: Self, allocator: *Allocator, name: []const u8) !?[]const HeaderEntry { pub fn get(self: Self, allocator: *Allocator, name: []const u8) !?[]const HeaderEntry {
const dex = self.getIndices(name) orelse return null; const dex = self.getIndices(name) orelse return null;
const buf = try allocator.alloc(HeaderEntry, dex.len); const buf = try allocator.alloc(HeaderEntry, dex.items.len);
var n: usize = 0; var n: usize = 0;
for (dex.span()) |idx| { for (dex.span()) |idx| {
buf[n] = self.data.at(idx); buf[n] = self.data.at(idx);
@ -301,7 +301,7 @@ pub const Headers = struct {
// adapted from mem.join // adapted from mem.join
const total_len = blk: { const total_len = blk: {
var sum: usize = dex.len - 1; // space for separator(s) var sum: usize = dex.items.len - 1; // space for separator(s)
for (dex.span()) |idx| for (dex.span()) |idx|
sum += self.data.at(idx).value.len; sum += self.data.at(idx).value.len;
break :blk sum; break :blk sum;
@ -330,7 +330,7 @@ pub const Headers = struct {
var it = self.index.iterator(); var it = self.index.iterator();
while (it.next()) |kv| { while (it.next()) |kv| {
var dex = &kv.value; var dex = &kv.value;
dex.len = 0; // keeps capacity available dex.items.len = 0; // keeps capacity available
} }
} }
{ // fill up indexes again; we know capacity is fine from before { // fill up indexes again; we know capacity is fine from before

View File

@ -54,7 +54,7 @@ pub fn InStream(
/// and the `std.ArrayList` has exactly `max_append_size` bytes appended. /// and the `std.ArrayList` has exactly `max_append_size` bytes appended.
pub fn readAllArrayList(self: Self, array_list: *std.ArrayList(u8), max_append_size: usize) !void { pub fn readAllArrayList(self: Self, array_list: *std.ArrayList(u8), max_append_size: usize) !void {
try array_list.ensureCapacity(math.min(max_append_size, 4096)); try array_list.ensureCapacity(math.min(max_append_size, 4096));
const original_len = array_list.len; const original_len = array_list.items.len;
var start_index: usize = original_len; var start_index: usize = original_len;
while (true) { while (true) {
array_list.expandToCapacity(); array_list.expandToCapacity();
@ -106,7 +106,7 @@ pub fn InStream(
return; return;
} }
if (array_list.len == max_size) { if (array_list.items.len == max_size) {
return error.StreamTooLong; return error.StreamTooLong;
} }

View File

@ -1556,7 +1556,7 @@ fn parseInternal(comptime T: type, token: Token, tokens: *TokenStream, options:
else => {}, else => {},
} }
try arraylist.ensureCapacity(arraylist.len + 1); try arraylist.ensureCapacity(arraylist.items.len + 1);
const v = try parseInternal(ptrInfo.child, tok, tokens, options); const v = try parseInternal(ptrInfo.child, tok, tokens, options);
arraylist.appendAssumeCapacity(v); arraylist.appendAssumeCapacity(v);
} }
@ -1874,7 +1874,7 @@ pub const Parser = struct {
try p.transition(&arena.allocator, input, s.i - 1, token); try p.transition(&arena.allocator, input, s.i - 1, token);
} }
debug.assert(p.stack.len == 1); debug.assert(p.stack.items.len == 1);
return ValueTree{ return ValueTree{
.arena = arena, .arena = arena,
@ -1888,7 +1888,7 @@ pub const Parser = struct {
switch (p.state) { switch (p.state) {
.ObjectKey => switch (token) { .ObjectKey => switch (token) {
.ObjectEnd => { .ObjectEnd => {
if (p.stack.len == 1) { if (p.stack.items.len == 1) {
return; return;
} }
@ -1907,8 +1907,8 @@ pub const Parser = struct {
}, },
}, },
.ObjectValue => { .ObjectValue => {
var object = &p.stack.items[p.stack.len - 2].Object; var object = &p.stack.items[p.stack.items.len - 2].Object;
var key = p.stack.items[p.stack.len - 1].String; var key = p.stack.items[p.stack.items.len - 1].String;
switch (token) { switch (token) {
.ObjectBegin => { .ObjectBegin => {
@ -1950,11 +1950,11 @@ pub const Parser = struct {
} }
}, },
.ArrayValue => { .ArrayValue => {
var array = &p.stack.items[p.stack.len - 1].Array; var array = &p.stack.items[p.stack.items.len - 1].Array;
switch (token) { switch (token) {
.ArrayEnd => { .ArrayEnd => {
if (p.stack.len == 1) { if (p.stack.items.len == 1) {
return; return;
} }
@ -2021,12 +2021,12 @@ pub const Parser = struct {
} }
fn pushToParent(p: *Parser, value: *const Value) !void { fn pushToParent(p: *Parser, value: *const Value) !void {
switch (p.stack.span()[p.stack.len - 1]) { switch (p.stack.span()[p.stack.items.len - 1]) {
// Object Parent -> [ ..., object, <key>, value ] // Object Parent -> [ ..., object, <key>, value ]
Value.String => |key| { Value.String => |key| {
_ = p.stack.pop(); _ = p.stack.pop();
var object = &p.stack.items[p.stack.len - 1].Object; var object = &p.stack.items[p.stack.items.len - 1].Object;
_ = try object.put(key, value.*); _ = try object.put(key, value.*);
p.state = .ObjectKey; p.state = .ObjectKey;
}, },
@ -2165,7 +2165,7 @@ test "json.parser.dynamic" {
testing.expect(animated.Bool == false); testing.expect(animated.Bool == false);
const array_of_object = image.Object.get("ArrayOfObject").?.value; const array_of_object = image.Object.get("ArrayOfObject").?.value;
testing.expect(array_of_object.Array.len == 1); testing.expect(array_of_object.Array.items.len == 1);
const obj0 = array_of_object.Array.at(0).Object.get("n").?.value; const obj0 = array_of_object.Array.at(0).Object.get("n").?.value;
testing.expect(mem.eql(u8, obj0.String, "m")); testing.expect(mem.eql(u8, obj0.String, "m"));

View File

@ -4,7 +4,6 @@ const math = std.math;
const mem = std.mem; const mem = std.mem;
const testing = std.testing; const testing = std.testing;
const Allocator = mem.Allocator; const Allocator = mem.Allocator;
const ArrayList = std.ArrayList;
const bn = @import("int.zig"); const bn = @import("int.zig");
const Limb = bn.Limb; const Limb = bn.Limb;

View File

@ -509,7 +509,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*
try linuxLookupName(&lookup_addrs, &canon, name, family, flags, port); try linuxLookupName(&lookup_addrs, &canon, name, family, flags, port);
result.addrs = try arena.alloc(Address, lookup_addrs.len); result.addrs = try arena.alloc(Address, lookup_addrs.items.len);
if (!canon.isNull()) { if (!canon.isNull()) {
result.canon_name = canon.toOwnedSlice(); result.canon_name = canon.toOwnedSlice();
} }
@ -554,7 +554,7 @@ fn linuxLookupName(
return name_err; return name_err;
} else { } else {
try linuxLookupNameFromHosts(addrs, canon, name, family, port); try linuxLookupNameFromHosts(addrs, canon, name, family, port);
if (addrs.len == 0) { if (addrs.items.len == 0) {
try linuxLookupNameFromDnsSearch(addrs, canon, name, family, port); try linuxLookupNameFromDnsSearch(addrs, canon, name, family, port);
} }
} }
@ -562,11 +562,11 @@ fn linuxLookupName(
try canon.resize(0); try canon.resize(0);
try linuxLookupNameFromNull(addrs, family, flags, port); try linuxLookupNameFromNull(addrs, family, flags, port);
} }
if (addrs.len == 0) return error.UnknownHostName; if (addrs.items.len == 0) return error.UnknownHostName;
// No further processing is needed if there are fewer than 2 // No further processing is needed if there are fewer than 2
// results or if there are only IPv4 results. // results or if there are only IPv4 results.
if (addrs.len == 1 or family == os.AF_INET) return; if (addrs.items.len == 1 or family == os.AF_INET) return;
const all_ip4 = for (addrs.span()) |addr| { const all_ip4 = for (addrs.span()) |addr| {
if (addr.addr.any.family != os.AF_INET) break false; if (addr.addr.any.family != os.AF_INET) break false;
} else true; } else true;
@ -908,7 +908,7 @@ fn linuxLookupNameFromDnsSearch(
canon.shrink(canon_name.len + 1); canon.shrink(canon_name.len + 1);
try canon.appendSlice(tok); try canon.appendSlice(tok);
try linuxLookupNameFromDns(addrs, canon, canon.span(), family, rc, port); try linuxLookupNameFromDns(addrs, canon, canon.span(), family, rc, port);
if (addrs.len != 0) return; if (addrs.items.len != 0) return;
} }
canon.shrink(canon_name.len); canon.shrink(canon_name.len);
@ -967,7 +967,7 @@ fn linuxLookupNameFromDns(
dnsParse(ap[i], ctx, dnsParseCallback) catch {}; dnsParse(ap[i], ctx, dnsParseCallback) catch {};
} }
if (addrs.len != 0) return; if (addrs.items.len != 0) return;
if (ap[0].len < 4 or (ap[0][3] & 15) == 2) return error.TemporaryNameServerFailure; if (ap[0].len < 4 or (ap[0][3] & 15) == 2) return error.TemporaryNameServerFailure;
if ((ap[0][3] & 15) == 0) return error.UnknownHostName; if ((ap[0][3] & 15) == 0) return error.UnknownHostName;
if ((ap[0][3] & 15) == 3) return; if ((ap[0][3] & 15) == 3) return;
@ -1049,7 +1049,7 @@ fn getResolvConf(allocator: *mem.Allocator, rc: *ResolvConf) !void {
} }
} }
if (rc.ns.len == 0) { if (rc.ns.items.len == 0) {
return linuxLookupNameFromNumericUnspec(&rc.ns, "127.0.0.1", 53); return linuxLookupNameFromNumericUnspec(&rc.ns, "127.0.0.1", 53);
} }
} }
@ -1078,7 +1078,7 @@ fn resMSendRc(
var ns_list = std.ArrayList(Address).init(rc.ns.allocator); var ns_list = std.ArrayList(Address).init(rc.ns.allocator);
defer ns_list.deinit(); defer ns_list.deinit();
try ns_list.resize(rc.ns.len); try ns_list.resize(rc.ns.items.len);
const ns = ns_list.span(); const ns = ns_list.span();
for (rc.ns.span()) |iplit, i| { for (rc.ns.span()) |iplit, i| {

View File

@ -171,7 +171,7 @@ fn usage(builder: *Builder, already_ran_build: bool, out_stream: var) !void {
\\ \\
); );
if (builder.available_options_list.len == 0) { if (builder.available_options_list.items.len == 0) {
try out_stream.print(" (none)\n", .{}); try out_stream.print(" (none)\n", .{});
} else { } else {
for (builder.available_options_list.span()) |option| { for (builder.available_options_list.span()) |option| {

View File

@ -475,7 +475,7 @@ pub fn utf16leToUtf8Alloc(allocator: *mem.Allocator, utf16le: []const u16) ![]u8
var it = Utf16LeIterator.init(utf16le); var it = Utf16LeIterator.init(utf16le);
while (try it.nextCodepoint()) |codepoint| { while (try it.nextCodepoint()) |codepoint| {
const utf8_len = utf8CodepointSequenceLength(codepoint) catch unreachable; const utf8_len = utf8CodepointSequenceLength(codepoint) catch unreachable;
try result.resize(result.len + utf8_len); try result.resize(result.items.len + utf8_len);
assert((utf8Encode(codepoint, result.items[out_index..]) catch unreachable) == utf8_len); assert((utf8Encode(codepoint, result.items[out_index..]) catch unreachable) == utf8_len);
out_index += utf8_len; out_index += utf8_len;
} }
@ -571,7 +571,7 @@ pub fn utf8ToUtf16LeWithNull(allocator: *mem.Allocator, utf8: []const u8) ![:0]u
} }
} }
const len = result.len; const len = result.items.len;
try result.append(0); try result.append(0);
return result.toOwnedSlice()[0..len :0]; return result.toOwnedSlice()[0..len :0];
} }

View File

@ -268,7 +268,7 @@ pub const LibCInstallation = struct {
try search_paths.append(line); try search_paths.append(line);
} }
} }
if (search_paths.len == 0) { if (search_paths.items.len == 0) {
return error.CCompilerCannotFindHeaders; return error.CCompilerCannotFindHeaders;
} }
@ -276,9 +276,9 @@ pub const LibCInstallation = struct {
const sys_include_dir_example_file = if (is_windows) "sys\\types.h" else "sys/errno.h"; const sys_include_dir_example_file = if (is_windows) "sys\\types.h" else "sys/errno.h";
var path_i: usize = 0; var path_i: usize = 0;
while (path_i < search_paths.len) : (path_i += 1) { while (path_i < search_paths.items.len) : (path_i += 1) {
// search in reverse order // search in reverse order
const search_path_untrimmed = search_paths.at(search_paths.len - path_i - 1); const search_path_untrimmed = search_paths.at(search_paths.items.len - path_i - 1);
const search_path = std.mem.trimLeft(u8, search_path_untrimmed, " "); const search_path = std.mem.trimLeft(u8, search_path_untrimmed, " ");
var search_dir = fs.cwd().openDir(search_path, .{}) catch |err| switch (err) { var search_dir = fs.cwd().openDir(search_path, .{}) catch |err| switch (err) {
error.FileNotFound, error.FileNotFound,

View File

@ -239,7 +239,7 @@ fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void {
} }
if (stdin_flag) { if (stdin_flag) {
if (input_files.len != 0) { if (input_files.items.len != 0) {
try stderr.writeAll("cannot use --stdin with positional arguments\n"); try stderr.writeAll("cannot use --stdin with positional arguments\n");
process.exit(1); process.exit(1);
} }
@ -273,7 +273,7 @@ fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void {
return; return;
} }
if (input_files.len == 0) { if (input_files.items.len == 0) {
try stderr.writeAll("expected at least one source file argument\n"); try stderr.writeAll("expected at least one source file argument\n");
process.exit(1); process.exit(1);
} }

View File

@ -4309,7 +4309,7 @@ fn makeRestorePoint(c: *Context) RestorePoint {
return RestorePoint{ return RestorePoint{
.c = c, .c = c,
.token_index = c.tree.tokens.len, .token_index = c.tree.tokens.len,
.src_buf_index = c.source_buffer.len, .src_buf_index = c.source_buffer.items.len,
}; };
} }
@ -4771,11 +4771,11 @@ fn appendToken(c: *Context, token_id: Token.Id, bytes: []const u8) !ast.TokenInd
fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8, args: var) !ast.TokenIndex { fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8, args: var) !ast.TokenIndex {
assert(token_id != .Invalid); assert(token_id != .Invalid);
const start_index = c.source_buffer.len; const start_index = c.source_buffer.items.len;
errdefer c.source_buffer.shrink(start_index); errdefer c.source_buffer.shrink(start_index);
try c.source_buffer.outStream().print(format, args); try c.source_buffer.outStream().print(format, args);
const end_index = c.source_buffer.len; const end_index = c.source_buffer.items.len;
const token_index = c.tree.tokens.len; const token_index = c.tree.tokens.len;
const new_token = try c.tree.tokens.addOne(); const new_token = try c.tree.tokens.addOne();
errdefer c.tree.tokens.shrink(token_index); errdefer c.tree.tokens.shrink(token_index);

View File

@ -113,7 +113,7 @@ fn parse(tokens: *const ArrayList(Token), token_index: *usize) ParseError!Node {
fn expandString(input: []const u8, output: *ArrayListSentineled(u8, 0)) !void { fn expandString(input: []const u8, output: *ArrayListSentineled(u8, 0)) !void {
const tokens = try tokenize(input); const tokens = try tokenize(input);
if (tokens.len == 1) { if (tokens.items.len == 1) {
return output.resize(0); return output.resize(0);
} }
@ -142,7 +142,7 @@ fn expandString(input: []const u8, output: *ArrayListSentineled(u8, 0)) !void {
const ExpandNodeError = error{OutOfMemory}; const ExpandNodeError = error{OutOfMemory};
fn expandNode(node: Node, output: *ArrayList(ArrayListSentineled(u8, 0))) ExpandNodeError!void { fn expandNode(node: Node, output: *ArrayList(ArrayListSentineled(u8, 0))) ExpandNodeError!void {
assert(output.len == 0); assert(output.items.len == 0);
switch (node) { switch (node) {
Node.Scalar => |scalar| { Node.Scalar => |scalar| {
try output.append(try ArrayListSentineled(u8, 0).init(global_allocator, scalar)); try output.append(try ArrayListSentineled(u8, 0).init(global_allocator, scalar));

View File

@ -879,13 +879,13 @@ pub const CompileErrorContext = struct {
var err_iter = ErrLineIter.init(stderr); var err_iter = ErrLineIter.init(stderr);
var i: usize = 0; var i: usize = 0;
ok = while (err_iter.next()) |line| : (i += 1) { ok = while (err_iter.next()) |line| : (i += 1) {
if (i >= self.case.expected_errors.len) break false; if (i >= self.case.expected_errors.items.len) break false;
const expected = self.case.expected_errors.at(i); const expected = self.case.expected_errors.at(i);
if (mem.indexOf(u8, line, expected) == null) break false; if (mem.indexOf(u8, line, expected) == null) break false;
continue; continue;
} else true; } else true;
ok = ok and i == self.case.expected_errors.len; ok = ok and i == self.case.expected_errors.items.len;
if (!ok) { if (!ok) {
warn("\n======== Expected these compile errors: ========\n", .{}); warn("\n======== Expected these compile errors: ========\n", .{});

View File

@ -194,7 +194,7 @@ const Dump = struct {
for (other_files) |other_file, i| { for (other_files) |other_file, i| {
const gop = try self.file_map.getOrPut(other_file.String); const gop = try self.file_map.getOrPut(other_file.String);
if (!gop.found_existing) { if (!gop.found_existing) {
gop.kv.value = self.file_list.len; gop.kv.value = self.file_list.items.len;
try self.file_list.append(other_file.String); try self.file_list.append(other_file.String);
} }
try other_file_to_mine.putNoClobber(i, gop.kv.value); try other_file_to_mine.putNoClobber(i, gop.kv.value);
@ -213,7 +213,7 @@ const Dump = struct {
}; };
const gop = try self.node_map.getOrPut(other_node); const gop = try self.node_map.getOrPut(other_node);
if (!gop.found_existing) { if (!gop.found_existing) {
gop.kv.value = self.node_list.len; gop.kv.value = self.node_list.items.len;
try self.node_list.append(other_node); try self.node_list.append(other_node);
} }
try other_ast_node_to_mine.putNoClobber(i, gop.kv.value); try other_ast_node_to_mine.putNoClobber(i, gop.kv.value);
@ -243,7 +243,7 @@ const Dump = struct {
}; };
const gop = try self.error_map.getOrPut(other_error); const gop = try self.error_map.getOrPut(other_error);
if (!gop.found_existing) { if (!gop.found_existing) {
gop.kv.value = self.error_list.len; gop.kv.value = self.error_list.items.len;
try self.error_list.append(other_error); try self.error_list.append(other_error);
} }
try other_error_to_mine.putNoClobber(i, gop.kv.value); try other_error_to_mine.putNoClobber(i, gop.kv.value);
@ -304,7 +304,7 @@ const Dump = struct {
) !void { ) !void {
const gop = try self.type_map.getOrPut(other_type); const gop = try self.type_map.getOrPut(other_type);
if (!gop.found_existing) { if (!gop.found_existing) {
gop.kv.value = self.type_list.len; gop.kv.value = self.type_list.items.len;
try self.type_list.append(other_type); try self.type_list.append(other_type);
} }
try other_types_to_mine.putNoClobber(other_type_index, gop.kv.value); try other_types_to_mine.putNoClobber(other_type_index, gop.kv.value);