Skip to content

rework ZIR memory layout; overhaul source locations #8266

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 100 commits into from
Apr 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
aef3e53
stage2: *WIP*: rework ZIR memory layout; overhaul source locations
andrewrk Mar 16, 2021
099af0e
stage2: rename zir_sema.zig to Sema.zig
andrewrk Mar 16, 2021
e430f3f
zir-memory-layout: fix @setEvalBranchQuota
g-w1 Mar 16, 2021
38b3d4b
stage2: work through some compile errors in Module and Sema
andrewrk Mar 17, 2021
66245ac
stage2: Module and Sema are compiling again
andrewrk Mar 18, 2021
f5aca4a
Merge remote-tracking branch 'origin/master' into zir-memory-layout
andrewrk Mar 18, 2021
b268223
stage2: get Module and Sema compiling again
andrewrk Mar 19, 2021
bd2154d
stage2: the code is compiling again
andrewrk Mar 19, 2021
abdbc11
stage2: codegen: update asm IR to new names
andrewrk Mar 19, 2021
e9810d9
zir-memory-layout: astgen: fill in identifier
g-w1 Mar 19, 2021
c50397c
llvm backend: use new srcloc
g-w1 Mar 19, 2021
a4f0ccd
zir-memory-layout: astgen: literals and *, &
g-w1 Mar 19, 2021
132df14
stage2: fix export source locations not being relative to Decl
andrewrk Mar 19, 2021
81a935a
stage2: fix some math oopsies and typos
andrewrk Mar 19, 2021
0357cd8
Sema: allocate inst_map with arena where appropriate
andrewrk Mar 19, 2021
937c43d
stage2: first pass at repairing ZIR printing
andrewrk Mar 20, 2021
56677f2
astgen: support blocks
andrewrk Mar 20, 2021
a710368
stage2: restructure LLVM backend
FireFox317 Mar 7, 2021
12eeb18
zir-memory-layout: astgen: more instructions
g-w1 Mar 20, 2021
907142a
zir-memory-layout: remove all absolute src consts
g-w1 Mar 20, 2021
5001044
astgen: implement function calls
andrewrk Mar 21, 2021
260c610
ZIR: move some un_tok tags to un_node instead
andrewrk Mar 21, 2021
8bad5df
astgen: implement inline assembly
andrewrk Mar 21, 2021
d8692b8
astgen: implement string literals
andrewrk Mar 21, 2021
7598a00
stage2: fix memory management of ZIR code
andrewrk Mar 21, 2021
7800ae0
astgen: fix not detecting volatile asm
andrewrk Mar 21, 2021
310a44d
zir: add negate/negate_wrap, implement astgen
ifreund Mar 21, 2021
4cfd5f6
astgen: implement simple binary operators
ifreund Mar 21, 2021
72bcdb6
astgen: implement bool_and/bool_or
ifreund Mar 21, 2021
07c2043
Sema: no explicit coercion needed for inline asm args
andrewrk Mar 22, 2021
5769c96
Sema: implement arithmetic
andrewrk Mar 22, 2021
7a55671
zir-memory-layout: astgen: varDecl
g-w1 Mar 22, 2021
4f3071a
cleanups from previous commit
andrewrk Mar 22, 2021
8111453
astgen: implement array types
ifreund Mar 22, 2021
f3770dc
astgen: implement pointer types
ifreund Mar 22, 2021
240b153
fix calculation in ensureCapacity
rsaunderson88-kw Mar 22, 2021
9f0b9b8
stage2: remove all async related code
ifreund Mar 22, 2021
2f391df
stage2: Sema improvements and boolean logic astgen
andrewrk Mar 23, 2021
568f333
astgen: improve the ensure_unused_result elision
andrewrk Mar 23, 2021
d24be85
stage2: fix `if` expressions
andrewrk Mar 23, 2021
f3e8073
astgen: implement assign operations
FireFox317 Mar 23, 2021
6681485
stage2: fix two return types to be Ref not Index
ifreund Mar 23, 2021
d73b047
stage2: rename fail to todo in LLVM backend
FireFox317 Mar 23, 2021
982df37
stage2: handle void value in genRet in LLVM backend
FireFox317 Mar 23, 2021
99cf9f8
astgen: fix an issue where the alloc wasnt elided
FireFox317 Mar 23, 2021
7194bae
astgen: implement typeof
FireFox317 Mar 23, 2021
8301439
Sema: use correct LazySrcLoc for resolvePeerTypes
FireFox317 Mar 23, 2021
866be09
stage2: add helper functions to clean up astgen Ref/Index
andrewrk Mar 23, 2021
af73f79
stage2: fix comptimeExpr and comptime function calls
andrewrk Mar 23, 2021
aa46a70
astgen: finishThenElseBlock: fix putting store_to_block_ptr in wrong …
andrewrk Mar 23, 2021
be673e6
stage2: implement inttype ZIR
andrewrk Mar 23, 2021
bf7c3e9
astgen: fixups regarding var decls and rl_ptr
andrewrk Mar 23, 2021
13ced07
stage2: fix while loops
andrewrk Mar 24, 2021
a1afe69
stage2: comment out failing test cases; implement more things
andrewrk Mar 24, 2021
0c60196
stage2: make zir.Inst.Ref a non-exhaustive enum
ifreund Mar 24, 2021
180dae4
stage2: further cleanups regarding zir.Inst.Ref
andrewrk Mar 24, 2021
0c6581e
stage2: fix memory leak when updating a function
andrewrk Mar 24, 2021
2c99fbb
astgen: implement orelse
FireFox317 Mar 23, 2021
3543373
stage2: add passing optional test case in LLVM backend
FireFox317 Mar 24, 2021
d73a494
stage2: cleanups from previous commits
andrewrk Mar 24, 2021
5227076
astgen: implement breaking from a block
FireFox317 Mar 24, 2021
ea42ab3
stage2: add block test cases llvm backend
FireFox317 Mar 24, 2021
01bfd83
stage2: clean up break / noreturn astgen
andrewrk Mar 25, 2021
12d18a3
stage2: enable passing tests
andrewrk Mar 25, 2021
31023de
stage2: implement inline while
andrewrk Mar 25, 2021
399bb2e
astgen: fix array access
andrewrk Mar 25, 2021
b9c5a1f
astgen: fix for loop expressions
andrewrk Mar 26, 2021
4fd3a2e
astgen: fix var decl source locations
andrewrk Mar 26, 2021
4bfcd10
stage2: fix `@compileLog`.
andrewrk Mar 26, 2021
b2deaf8
stage2: improve source locations of Decl access
andrewrk Mar 26, 2021
5eea13f
astgen: implement slicing
ifreund Mar 26, 2021
d8ee879
astgen: implement more builtin functions
ifreund Mar 26, 2021
22338d7
astgen: implement float literals
ifreund Mar 26, 2021
a217ad5
astgen: fix result location for sliced objects
ifreund Mar 26, 2021
a72bfd0
astgen: fix continue expressions
andrewrk Mar 27, 2021
da731e1
stage2: implement source location: .node_offset_var_decl_ty
andrewrk Mar 27, 2021
1f5617a
stage2: implement bitwise expr and error literals
andrewrk Mar 27, 2021
95cc457
stage2: enable passing tests
andrewrk Mar 27, 2021
68f4eb0
stage2: fully implement Type.eql for pointers
andrewrk Mar 28, 2021
402f87a
stage2: rename WipZirCode => AstGen, astgen.zig => AstGen.zig
ifreund Mar 28, 2021
d123a5e
AstGen: scope result location related functions
ifreund Mar 28, 2021
d5d8808
translate-c: fix typo made in prior commit
ifreund Mar 28, 2021
f80f8a7
AstGen: pass *GenZir as the first arg, not *Module
ifreund Mar 28, 2021
0005b34
stage2: implement sema for @errorToInt and @intToError
g-w1 Mar 26, 2021
8f469c1
stage2: fix error sets
andrewrk Mar 29, 2021
281a7ba
Merge remote-tracking branch 'origin/master' into zir-memory-layout
andrewrk Mar 29, 2021
623d5f4
stage2: guidance on how to implement switch expressions
andrewrk Mar 29, 2021
195ddab
Sema: implement switch expressions
andrewrk Mar 30, 2021
2a1dd17
stage2: rework AstGen for switch expressions
andrewrk Mar 31, 2021
549af58
AstGen: switch expressions properly handle result locations
andrewrk Mar 31, 2021
c7b09be
AstGen: improve switch expressions
andrewrk Mar 31, 2021
e272c29
Sema: implement switch validation for ranges
andrewrk Mar 31, 2021
abd06d8
stage2: clean up RangeSet and fix swapped Sema switch logic for lhs/rhs
andrewrk Mar 31, 2021
08eedc9
Sema: fix else case code generation for switch
andrewrk Mar 31, 2021
3cebaaa
astgen: improved handling of coercion
andrewrk Apr 1, 2021
fedc9eb
stage2: cbe: restore all previously passing tests!
g-w1 Apr 1, 2021
cec766f
stage2: compile error for duplicate switch value on boolean
andrewrk Apr 1, 2021
e8143f6
stage2: compile error for duplicate switch value on sparse
andrewrk Apr 1, 2021
b27d052
stage2: finish source location reworkings in the branch
andrewrk Apr 1, 2021
c9e31fe
stage2: finish implementation of LazySrcLoc
andrewrk Apr 1, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ set(ZIG_STAGE2_SOURCES
"${CMAKE_SOURCE_DIR}/src/ThreadPool.zig"
"${CMAKE_SOURCE_DIR}/src/TypedValue.zig"
"${CMAKE_SOURCE_DIR}/src/WaitGroup.zig"
"${CMAKE_SOURCE_DIR}/src/astgen.zig"
"${CMAKE_SOURCE_DIR}/src/AstGen.zig"
"${CMAKE_SOURCE_DIR}/src/clang.zig"
"${CMAKE_SOURCE_DIR}/src/clang_options.zig"
"${CMAKE_SOURCE_DIR}/src/clang_options_data.zig"
Expand Down Expand Up @@ -591,7 +591,7 @@ set(ZIG_STAGE2_SOURCES
"${CMAKE_SOURCE_DIR}/src/value.zig"
"${CMAKE_SOURCE_DIR}/src/windows_sdk.zig"
"${CMAKE_SOURCE_DIR}/src/zir.zig"
"${CMAKE_SOURCE_DIR}/src/zir_sema.zig"
"${CMAKE_SOURCE_DIR}/src/Sema.zig"
)

if(MSVC)
Expand Down
89 changes: 48 additions & 41 deletions lib/std/enums.zig
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub fn EnumFieldStruct(comptime E: type, comptime Data: type, comptime field_def
.fields = fields,
.decls = &[_]std.builtin.TypeInfo.Declaration{},
.is_tuple = false,
}});
} });
}

/// Looks up the supplied fields in the given enum type.
Expand Down Expand Up @@ -70,7 +70,7 @@ pub fn values(comptime E: type) []const E {

test "std.enum.values" {
const E = extern enum { a, b, c, d = 0 };
testing.expectEqualSlices(E, &.{.a, .b, .c, .d}, values(E));
testing.expectEqualSlices(E, &.{ .a, .b, .c, .d }, values(E));
}

/// Returns the set of all unique named values in the given enum, in
Expand All @@ -82,10 +82,10 @@ pub fn uniqueValues(comptime E: type) []const E {

test "std.enum.uniqueValues" {
const E = extern enum { a, b, c, d = 0, e, f = 3 };
testing.expectEqualSlices(E, &.{.a, .b, .c, .f}, uniqueValues(E));
testing.expectEqualSlices(E, &.{ .a, .b, .c, .f }, uniqueValues(E));

const F = enum { a, b, c };
testing.expectEqualSlices(F, &.{.a, .b, .c}, uniqueValues(F));
testing.expectEqualSlices(F, &.{ .a, .b, .c }, uniqueValues(F));
}

/// Returns the set of all unique field values in the given enum, in
Expand All @@ -102,8 +102,7 @@ pub fn uniqueFields(comptime E: type) []const EnumField {
}

var unique_fields: []const EnumField = &[_]EnumField{};
outer:
for (raw_fields) |candidate| {
outer: for (raw_fields) |candidate| {
for (unique_fields) |u| {
if (u.value == candidate.value)
continue :outer;
Expand All @@ -116,28 +115,25 @@ pub fn uniqueFields(comptime E: type) []const EnumField {
}

/// Determines the length of a direct-mapped enum array, indexed by
/// @intCast(usize, @enumToInt(enum_value)). The enum must be exhaustive.
/// @intCast(usize, @enumToInt(enum_value)).
/// If the enum is non-exhaustive, the resulting length will only be enough
/// to hold all explicit fields.
/// If the enum contains any fields with values that cannot be represented
/// by usize, a compile error is issued. The max_unused_slots parameter limits
/// the total number of items which have no matching enum key (holes in the enum
/// numbering). So for example, if an enum has values 1, 2, 5, and 6, max_unused_slots
/// must be at least 3, to allow unused slots 0, 3, and 4.
fn directEnumArrayLen(comptime E: type, comptime max_unused_slots: comptime_int) comptime_int {
const info = @typeInfo(E).Enum;
if (!info.is_exhaustive) {
@compileError("Cannot create direct array of non-exhaustive enum "++@typeName(E));
}

var max_value: comptime_int = -1;
const max_usize: comptime_int = ~@as(usize, 0);
const fields = uniqueFields(E);
for (fields) |f| {
if (f.value < 0) {
@compileError("Cannot create a direct enum array for "++@typeName(E)++", field ."++f.name++" has a negative value.");
@compileError("Cannot create a direct enum array for " ++ @typeName(E) ++ ", field ." ++ f.name ++ " has a negative value.");
}
if (f.value > max_value) {
if (f.value > max_usize) {
@compileError("Cannot create a direct enum array for "++@typeName(E)++", field ."++f.name++" is larger than the max value of usize.");
@compileError("Cannot create a direct enum array for " ++ @typeName(E) ++ ", field ." ++ f.name ++ " is larger than the max value of usize.");
}
max_value = f.value;
}
Expand All @@ -147,14 +143,16 @@ fn directEnumArrayLen(comptime E: type, comptime max_unused_slots: comptime_int)
if (unused_slots > max_unused_slots) {
const unused_str = std.fmt.comptimePrint("{d}", .{unused_slots});
const allowed_str = std.fmt.comptimePrint("{d}", .{max_unused_slots});
@compileError("Cannot create a direct enum array for "++@typeName(E)++". It would have "++unused_str++" unused slots, but only "++allowed_str++" are allowed.");
@compileError("Cannot create a direct enum array for " ++ @typeName(E) ++ ". It would have " ++ unused_str ++ " unused slots, but only " ++ allowed_str ++ " are allowed.");
}

return max_value + 1;
}

/// Initializes an array of Data which can be indexed by
/// @intCast(usize, @enumToInt(enum_value)). The enum must be exhaustive.
/// @intCast(usize, @enumToInt(enum_value)).
/// If the enum is non-exhaustive, the resulting array will only be large enough
/// to hold all explicit fields.
/// If the enum contains any fields with values that cannot be represented
/// by usize, a compile error is issued. The max_unused_slots parameter limits
/// the total number of items which have no matching enum key (holes in the enum
Expand Down Expand Up @@ -243,9 +241,9 @@ pub fn nameCast(comptime E: type, comptime value: anytype) E {
if (@hasField(E, n)) {
return @field(E, n);
}
@compileError("Enum "++@typeName(E)++" has no field named "++n);
@compileError("Enum " ++ @typeName(E) ++ " has no field named " ++ n);
}
@compileError("Cannot cast from "++@typeName(@TypeOf(value))++" to "++@typeName(E));
@compileError("Cannot cast from " ++ @typeName(@TypeOf(value)) ++ " to " ++ @typeName(E));
}
}

Expand All @@ -256,7 +254,7 @@ test "std.enums.nameCast" {
testing.expectEqual(A.a, nameCast(A, A.a));
testing.expectEqual(A.a, nameCast(A, B.a));
testing.expectEqual(A.a, nameCast(A, "a"));
testing.expectEqual(A.a, nameCast(A, @as(*const[1]u8, "a")));
testing.expectEqual(A.a, nameCast(A, @as(*const [1]u8, "a")));
testing.expectEqual(A.a, nameCast(A, @as([:0]const u8, "a")));
testing.expectEqual(A.a, nameCast(A, @as([]const u8, "a")));

Expand Down Expand Up @@ -398,12 +396,12 @@ pub fn EnumArray(comptime E: type, comptime V: type) type {
pub fn NoExtension(comptime Self: type) type {
return NoExt;
}
const NoExt = struct{};
const NoExt = struct {};

/// A set type with an Indexer mapping from keys to indices.
/// Presence or absence is stored as a dense bitfield. This
/// type does no allocation and can be copied by value.
pub fn IndexedSet(comptime I: type, comptime Ext: fn(type)type) type {
pub fn IndexedSet(comptime I: type, comptime Ext: fn (type) type) type {
comptime ensureIndexer(I);
return struct {
const Self = @This();
Expand All @@ -422,7 +420,7 @@ pub fn IndexedSet(comptime I: type, comptime Ext: fn(type)type) type {

bits: BitSet = BitSet.initEmpty(),

/// Returns a set containing all possible keys.
/// Returns a set containing all possible keys.
pub fn initFull() Self {
return .{ .bits = BitSet.initFull() };
}
Expand Down Expand Up @@ -492,7 +490,8 @@ pub fn IndexedSet(comptime I: type, comptime Ext: fn(type)type) type {
pub fn next(self: *Iterator) ?Key {
return if (self.inner.next()) |index|
Indexer.keyForIndex(index)
else null;
else
null;
}
};
};
Expand All @@ -501,7 +500,7 @@ pub fn IndexedSet(comptime I: type, comptime Ext: fn(type)type) type {
/// A map from keys to values, using an index lookup. Uses a
/// bitfield to track presence and a dense array of values.
/// This type does no allocation and can be copied by value.
pub fn IndexedMap(comptime I: type, comptime V: type, comptime Ext: fn(type)type) type {
pub fn IndexedMap(comptime I: type, comptime V: type, comptime Ext: fn (type) type) type {
comptime ensureIndexer(I);
return struct {
const Self = @This();
Expand Down Expand Up @@ -652,15 +651,16 @@ pub fn IndexedMap(comptime I: type, comptime V: type, comptime Ext: fn(type)type
.key = Indexer.keyForIndex(index),
.value = &self.values[index],
}
else null;
else
null;
}
};
};
}

/// A dense array of values, using an indexed lookup.
/// This type does no allocation and can be copied by value.
pub fn IndexedArray(comptime I: type, comptime V: type, comptime Ext: fn(type)type) type {
pub fn IndexedArray(comptime I: type, comptime V: type, comptime Ext: fn (type) type) type {
comptime ensureIndexer(I);
return struct {
const Self = @This();
Expand Down Expand Up @@ -769,9 +769,9 @@ pub fn ensureIndexer(comptime T: type) void {
if (!@hasDecl(T, "count")) @compileError("Indexer must have decl count: usize.");
if (@TypeOf(T.count) != usize) @compileError("Indexer.count must be a usize.");
if (!@hasDecl(T, "indexOf")) @compileError("Indexer.indexOf must be a fn(Key)usize.");
if (@TypeOf(T.indexOf) != fn(T.Key)usize) @compileError("Indexer must have decl indexOf: fn(Key)usize.");
if (@TypeOf(T.indexOf) != fn (T.Key) usize) @compileError("Indexer must have decl indexOf: fn(Key)usize.");
if (!@hasDecl(T, "keyForIndex")) @compileError("Indexer must have decl keyForIndex: fn(usize)Key.");
if (@TypeOf(T.keyForIndex) != fn(usize)T.Key) @compileError("Indexer.keyForIndex must be a fn(usize)Key.");
if (@TypeOf(T.keyForIndex) != fn (usize) T.Key) @compileError("Indexer.keyForIndex must be a fn(usize)Key.");
}
}

Expand Down Expand Up @@ -802,14 +802,18 @@ pub fn EnumIndexer(comptime E: type) type {
return struct {
pub const Key = E;
pub const count: usize = 0;
pub fn indexOf(e: E) usize { unreachable; }
pub fn keyForIndex(i: usize) E { unreachable; }
pub fn indexOf(e: E) usize {
unreachable;
}
pub fn keyForIndex(i: usize) E {
unreachable;
}
};
}
std.sort.sort(EnumField, &fields, {}, ascByValue);
const min = fields[0].value;
const max = fields[fields.len-1].value;
if (max - min == fields.len-1) {
const max = fields[fields.len - 1].value;
if (max - min == fields.len - 1) {
return struct {
pub const Key = E;
pub const count = fields.len;
Expand Down Expand Up @@ -844,7 +848,7 @@ pub fn EnumIndexer(comptime E: type) type {
}

test "std.enums.EnumIndexer dense zeroed" {
const E = enum{ b = 1, a = 0, c = 2 };
const E = enum { b = 1, a = 0, c = 2 };
const Indexer = EnumIndexer(E);
ensureIndexer(Indexer);
testing.expectEqual(E, Indexer.Key);
Expand Down Expand Up @@ -908,7 +912,7 @@ test "std.enums.EnumIndexer sparse" {
}

test "std.enums.EnumIndexer repeats" {
const E = extern enum{ a = -2, c = 6, b = 4, b2 = 4 };
const E = extern enum { a = -2, c = 6, b = 4, b2 = 4 };
const Indexer = EnumIndexer(E);
ensureIndexer(Indexer);
testing.expectEqual(E, Indexer.Key);
Expand Down Expand Up @@ -957,7 +961,8 @@ test "std.enums.EnumSet" {
}

var mut = Set.init(.{
.a=true, .c=true,
.a = true,
.c = true,
});
testing.expectEqual(@as(usize, 2), mut.count());
testing.expectEqual(true, mut.contains(.a));
Expand Down Expand Up @@ -986,15 +991,15 @@ test "std.enums.EnumSet" {
testing.expectEqual(@as(?E, null), it.next());
}

mut.toggleSet(Set.init(.{ .a=true, .b=true }));
mut.toggleSet(Set.init(.{ .a = true, .b = true }));
testing.expectEqual(@as(usize, 2), mut.count());
testing.expectEqual(true, mut.contains(.a));
testing.expectEqual(false, mut.contains(.b));
testing.expectEqual(false, mut.contains(.c));
testing.expectEqual(true, mut.contains(.d));
testing.expectEqual(true, mut.contains(.e)); // aliases a

mut.setUnion(Set.init(.{ .a=true, .b=true }));
mut.setUnion(Set.init(.{ .a = true, .b = true }));
testing.expectEqual(@as(usize, 3), mut.count());
testing.expectEqual(true, mut.contains(.a));
testing.expectEqual(true, mut.contains(.b));
Expand All @@ -1009,7 +1014,7 @@ test "std.enums.EnumSet" {
testing.expectEqual(false, mut.contains(.c));
testing.expectEqual(true, mut.contains(.d));

mut.setIntersection(Set.init(.{ .a=true, .b=true }));
mut.setIntersection(Set.init(.{ .a = true, .b = true }));
testing.expectEqual(@as(usize, 1), mut.count());
testing.expectEqual(true, mut.contains(.a));
testing.expectEqual(false, mut.contains(.b));
Expand Down Expand Up @@ -1072,7 +1077,7 @@ test "std.enums.EnumArray sized" {
const undef = Array.initUndefined();
var inst = Array.initFill(5);
const inst2 = Array.init(.{ .a = 1, .b = 2, .c = 3, .d = 4 });
const inst3 = Array.initDefault(6, .{.b = 4, .c = 2});
const inst3 = Array.initDefault(6, .{ .b = 4, .c = 2 });

testing.expectEqual(@as(usize, 5), inst.get(.a));
testing.expectEqual(@as(usize, 5), inst.get(.b));
Expand Down Expand Up @@ -1272,10 +1277,12 @@ test "std.enums.EnumMap sized" {
var iter = a.iterator();
const Entry = Map.Entry;
testing.expectEqual(@as(?Entry, Entry{
.key = .b, .value = &a.values[1],
.key = .b,
.value = &a.values[1],
}), iter.next());
testing.expectEqual(@as(?Entry, Entry{
.key = .d, .value = &a.values[3],
.key = .d,
.value = &a.values[3],
}), iter.next());
testing.expectEqual(@as(?Entry, null), iter.next());
}
2 changes: 1 addition & 1 deletion lib/std/zig.zig
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub const Tokenizer = tokenizer.Tokenizer;
pub const fmtId = @import("zig/fmt.zig").fmtId;
pub const fmtEscapes = @import("zig/fmt.zig").fmtEscapes;
pub const parse = @import("zig/parse.zig").parse;
pub const parseStringLiteral = @import("zig/string_literal.zig").parse;
pub const string_literal = @import("zig/string_literal.zig");
pub const ast = @import("zig/ast.zig");
pub const system = @import("zig/system.zig");
pub const CrossTarget = @import("zig/cross_target.zig").CrossTarget;
Expand Down
14 changes: 10 additions & 4 deletions lib/std/zig/ast.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1252,6 +1252,7 @@ pub const Tree = struct {
buffer[0] = data.lhs;
const params = if (data.lhs == 0) buffer[0..0] else buffer[0..1];
return tree.fullFnProto(.{
.proto_node = node,
.fn_token = tree.nodes.items(.main_token)[node],
.return_type = data.rhs,
.params = params,
Expand All @@ -1267,6 +1268,7 @@ pub const Tree = struct {
const params_range = tree.extraData(data.lhs, Node.SubRange);
const params = tree.extra_data[params_range.start..params_range.end];
return tree.fullFnProto(.{
.proto_node = node,
.fn_token = tree.nodes.items(.main_token)[node],
.return_type = data.rhs,
.params = params,
Expand All @@ -1283,6 +1285,7 @@ pub const Tree = struct {
buffer[0] = extra.param;
const params = if (extra.param == 0) buffer[0..0] else buffer[0..1];
return tree.fullFnProto(.{
.proto_node = node,
.fn_token = tree.nodes.items(.main_token)[node],
.return_type = data.rhs,
.params = params,
Expand All @@ -1298,6 +1301,7 @@ pub const Tree = struct {
const extra = tree.extraData(data.lhs, Node.FnProto);
const params = tree.extra_data[extra.params_start..extra.params_end];
return tree.fullFnProto(.{
.proto_node = node,
.fn_token = tree.nodes.items(.main_token)[node],
.return_type = data.rhs,
.params = params,
Expand Down Expand Up @@ -1430,7 +1434,7 @@ pub const Tree = struct {
.ast = .{
.lbracket = tree.nodes.items(.main_token)[node],
.elem_count = data.lhs,
.sentinel = null,
.sentinel = 0,
.elem_type = data.rhs,
},
};
Expand All @@ -1440,6 +1444,7 @@ pub const Tree = struct {
assert(tree.nodes.items(.tag)[node] == .array_type_sentinel);
const data = tree.nodes.items(.data)[node];
const extra = tree.extraData(data.rhs, Node.ArrayTypeSentinel);
assert(extra.sentinel != 0);
return .{
.ast = .{
.lbracket = tree.nodes.items(.main_token)[node],
Expand Down Expand Up @@ -2119,6 +2124,7 @@ pub const full = struct {
ast: Ast,

pub const Ast = struct {
proto_node: Node.Index,
fn_token: TokenIndex,
return_type: Node.Index,
params: []const Node.Index,
Expand Down Expand Up @@ -2262,7 +2268,7 @@ pub const full = struct {
pub const Ast = struct {
lbracket: TokenIndex,
elem_count: Node.Index,
sentinel: ?Node.Index,
sentinel: Node.Index,
elem_type: Node.Index,
};
};
Expand Down Expand Up @@ -2549,9 +2555,9 @@ pub const Node = struct {
@"await",
/// `?lhs`. rhs unused. main_token is the `?`.
optional_type,
/// `[lhs]rhs`. lhs can be omitted to make it a slice.
/// `[lhs]rhs`.
array_type,
/// `[lhs:a]b`. `array_type_sentinel[rhs]`.
/// `[lhs:a]b`. `ArrayTypeSentinel[rhs]`.
array_type_sentinel,
/// `[*]align(lhs) rhs`. lhs can be omitted.
/// `*align(lhs) rhs`. lhs can be omitted.
Expand Down
Loading