Skip to content

Commit 687bd92

Browse files
committedJul 12, 2018
self-hosted: generate zig IR for simple function
no tests for this yet. I think the quickest path to testing will be creating the .o files and linking with libc, executing, and then comparing output.
1 parent ce11d6d commit 687bd92

File tree

11 files changed

+1555
-315
lines changed

11 files changed

+1555
-315
lines changed
 

‎src-self-hosted/decl.zig

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
const std = @import("std");
2+
const Allocator = mem.Allocator;
3+
const mem = std.mem;
4+
const ast = std.zig.ast;
5+
const Visib = @import("visib.zig").Visib;
6+
const ParsedFile = @import("parsed_file.zig").ParsedFile;
7+
const event = std.event;
8+
const Value = @import("value.zig").Value;
9+
const Token = std.zig.Token;
10+
const errmsg = @import("errmsg.zig");
11+
const Scope = @import("scope.zig").Scope;
12+
const Module = @import("module.zig").Module;
13+
14+
pub const Decl = struct {
15+
id: Id,
16+
name: []const u8,
17+
visib: Visib,
18+
resolution: event.Future(Module.BuildError!void),
19+
resolution_in_progress: u8,
20+
parsed_file: *ParsedFile,
21+
parent_scope: *Scope,
22+
23+
pub const Table = std.HashMap([]const u8, *Decl, mem.hash_slice_u8, mem.eql_slice_u8);
24+
25+
pub fn isExported(base: *const Decl, tree: *ast.Tree) bool {
26+
switch (base.id) {
27+
Id.Fn => {
28+
const fn_decl = @fieldParentPtr(Fn, "base", base);
29+
return fn_decl.isExported(tree);
30+
},
31+
else => return false,
32+
}
33+
}
34+
35+
pub fn getSpan(base: *const Decl) errmsg.Span {
36+
switch (base.id) {
37+
Id.Fn => {
38+
const fn_decl = @fieldParentPtr(Fn, "base", base);
39+
const fn_proto = fn_decl.fn_proto;
40+
const start = fn_proto.fn_token;
41+
const end = fn_proto.name_token orelse start;
42+
return errmsg.Span{
43+
.first = start,
44+
.last = end + 1,
45+
};
46+
},
47+
else => @panic("TODO"),
48+
}
49+
}
50+
51+
pub const Id = enum {
52+
Var,
53+
Fn,
54+
CompTime,
55+
};
56+
57+
pub const Var = struct {
58+
base: Decl,
59+
};
60+
61+
pub const Fn = struct {
62+
base: Decl,
63+
value: Val,
64+
fn_proto: *const ast.Node.FnProto,
65+
66+
// TODO https://github.com/ziglang/zig/issues/683 and then make this anonymous
67+
pub const Val = union {
68+
Unresolved: void,
69+
Ok: *Value.Fn,
70+
};
71+
72+
pub fn externLibName(self: Fn, tree: *ast.Tree) ?[]const u8 {
73+
return if (self.fn_proto.extern_export_inline_token) |tok_index| x: {
74+
const token = tree.tokens.at(tok_index);
75+
break :x switch (token.id) {
76+
Token.Id.Extern => tree.tokenSlicePtr(token),
77+
else => null,
78+
};
79+
} else null;
80+
}
81+
82+
pub fn isExported(self: Fn, tree: *ast.Tree) bool {
83+
if (self.fn_proto.extern_export_inline_token) |tok_index| {
84+
const token = tree.tokens.at(tok_index);
85+
return token.id == Token.Id.Keyword_export;
86+
} else {
87+
return false;
88+
}
89+
}
90+
};
91+
92+
pub const CompTime = struct {
93+
base: Decl,
94+
};
95+
};
96+

‎src-self-hosted/ir.zig

+645-100
Large diffs are not rendered by default.

‎src-self-hosted/module.zig

+186-197
Large diffs are not rendered by default.

‎src-self-hosted/parsed_file.zig

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
const ast = @import("std").zig.ast;
2+
3+
pub const ParsedFile = struct {
4+
tree: ast.Tree,
5+
realpath: []const u8,
6+
};

‎src-self-hosted/scope.zig

+224-6
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,234 @@
1+
const std = @import("std");
2+
const Allocator = mem.Allocator;
3+
const Decl = @import("decl.zig").Decl;
4+
const Module = @import("module.zig").Module;
5+
const mem = std.mem;
6+
const ast = std.zig.ast;
7+
const Value = @import("value.zig").Value;
8+
const ir = @import("ir.zig");
9+
110
pub const Scope = struct {
211
id: Id,
3-
parent: *Scope,
12+
parent: ?*Scope,
13+
ref_count: usize,
14+
15+
pub fn ref(base: *Scope) void {
16+
base.ref_count += 1;
17+
}
18+
19+
pub fn deref(base: *Scope, module: *Module) void {
20+
base.ref_count -= 1;
21+
if (base.ref_count == 0) {
22+
if (base.parent) |parent| parent.deref(module);
23+
switch (base.id) {
24+
Id.Decls => @fieldParentPtr(Decls, "base", base).destroy(),
25+
Id.Block => @fieldParentPtr(Block, "base", base).destroy(module),
26+
Id.FnDef => @fieldParentPtr(FnDef, "base", base).destroy(module),
27+
Id.CompTime => @fieldParentPtr(CompTime, "base", base).destroy(module),
28+
Id.Defer => @fieldParentPtr(Defer, "base", base).destroy(module),
29+
Id.DeferExpr => @fieldParentPtr(DeferExpr, "base", base).destroy(module),
30+
}
31+
}
32+
}
33+
34+
pub fn findFnDef(base: *Scope) ?*FnDef {
35+
var scope = base;
36+
while (true) {
37+
switch (scope.id) {
38+
Id.FnDef => return @fieldParentPtr(FnDef, "base", base),
39+
Id.Decls => return null,
40+
41+
Id.Block,
42+
Id.Defer,
43+
Id.DeferExpr,
44+
Id.CompTime,
45+
=> scope = scope.parent orelse return null,
46+
}
47+
}
48+
}
449

550
pub const Id = enum {
651
Decls,
752
Block,
8-
Defer,
9-
DeferExpr,
10-
VarDecl,
11-
CImport,
12-
Loop,
1353
FnDef,
1454
CompTime,
55+
Defer,
56+
DeferExpr,
57+
};
58+
59+
pub const Decls = struct {
60+
base: Scope,
61+
table: Decl.Table,
62+
63+
/// Creates a Decls scope with 1 reference
64+
pub fn create(module: *Module, parent: ?*Scope) !*Decls {
65+
const self = try module.a().create(Decls{
66+
.base = Scope{
67+
.id = Id.Decls,
68+
.parent = parent,
69+
.ref_count = 1,
70+
},
71+
.table = undefined,
72+
});
73+
errdefer module.a().destroy(self);
74+
75+
self.table = Decl.Table.init(module.a());
76+
errdefer self.table.deinit();
77+
78+
if (parent) |p| p.ref();
79+
80+
return self;
81+
}
82+
83+
pub fn destroy(self: *Decls) void {
84+
self.table.deinit();
85+
self.table.allocator.destroy(self);
86+
}
87+
};
88+
89+
pub const Block = struct {
90+
base: Scope,
91+
incoming_values: std.ArrayList(*ir.Instruction),
92+
incoming_blocks: std.ArrayList(*ir.BasicBlock),
93+
end_block: *ir.BasicBlock,
94+
is_comptime: *ir.Instruction,
95+
96+
/// Creates a Block scope with 1 reference
97+
pub fn create(module: *Module, parent: ?*Scope) !*Block {
98+
const self = try module.a().create(Block{
99+
.base = Scope{
100+
.id = Id.Block,
101+
.parent = parent,
102+
.ref_count = 1,
103+
},
104+
.incoming_values = undefined,
105+
.incoming_blocks = undefined,
106+
.end_block = undefined,
107+
.is_comptime = undefined,
108+
});
109+
errdefer module.a().destroy(self);
110+
111+
if (parent) |p| p.ref();
112+
return self;
113+
}
114+
115+
pub fn destroy(self: *Block, module: *Module) void {
116+
module.a().destroy(self);
117+
}
118+
};
119+
120+
pub const FnDef = struct {
121+
base: Scope,
122+
123+
/// This reference is not counted so that the scope can get destroyed with the function
124+
fn_val: *Value.Fn,
125+
126+
/// Creates a FnDef scope with 1 reference
127+
/// Must set the fn_val later
128+
pub fn create(module: *Module, parent: ?*Scope) !*FnDef {
129+
const self = try module.a().create(FnDef{
130+
.base = Scope{
131+
.id = Id.FnDef,
132+
.parent = parent,
133+
.ref_count = 1,
134+
},
135+
.fn_val = undefined,
136+
});
137+
138+
if (parent) |p| p.ref();
139+
140+
return self;
141+
}
142+
143+
pub fn destroy(self: *FnDef, module: *Module) void {
144+
module.a().destroy(self);
145+
}
146+
};
147+
148+
pub const CompTime = struct {
149+
base: Scope,
150+
151+
/// Creates a CompTime scope with 1 reference
152+
pub fn create(module: *Module, parent: ?*Scope) !*CompTime {
153+
const self = try module.a().create(CompTime{
154+
.base = Scope{
155+
.id = Id.CompTime,
156+
.parent = parent,
157+
.ref_count = 1,
158+
},
159+
});
160+
161+
if (parent) |p| p.ref();
162+
return self;
163+
}
164+
165+
pub fn destroy(self: *CompTime, module: *Module) void {
166+
module.a().destroy(self);
167+
}
168+
};
169+
170+
pub const Defer = struct {
171+
base: Scope,
172+
defer_expr_scope: *DeferExpr,
173+
kind: Kind,
174+
175+
pub const Kind = enum {
176+
ScopeExit,
177+
ErrorExit,
178+
};
179+
180+
/// Creates a Defer scope with 1 reference
181+
pub fn create(
182+
module: *Module,
183+
parent: ?*Scope,
184+
kind: Kind,
185+
defer_expr_scope: *DeferExpr,
186+
) !*Defer {
187+
const self = try module.a().create(Defer{
188+
.base = Scope{
189+
.id = Id.Defer,
190+
.parent = parent,
191+
.ref_count = 1,
192+
},
193+
.defer_expr_scope = defer_expr_scope,
194+
.kind = kind,
195+
});
196+
errdefer module.a().destroy(self);
197+
198+
defer_expr_scope.base.ref();
199+
200+
if (parent) |p| p.ref();
201+
return self;
202+
}
203+
204+
pub fn destroy(self: *Defer, module: *Module) void {
205+
self.defer_expr_scope.base.deref(module);
206+
module.a().destroy(self);
207+
}
208+
};
209+
210+
pub const DeferExpr = struct {
211+
base: Scope,
212+
expr_node: *ast.Node,
213+
214+
/// Creates a DeferExpr scope with 1 reference
215+
pub fn create(module: *Module, parent: ?*Scope, expr_node: *ast.Node) !*DeferExpr {
216+
const self = try module.a().create(DeferExpr{
217+
.base = Scope{
218+
.id = Id.DeferExpr,
219+
.parent = parent,
220+
.ref_count = 1,
221+
},
222+
.expr_node = expr_node,
223+
});
224+
errdefer module.a().destroy(self);
225+
226+
if (parent) |p| p.ref();
227+
return self;
228+
}
229+
230+
pub fn destroy(self: *DeferExpr, module: *Module) void {
231+
module.a().destroy(self);
232+
}
15233
};
16234
};

‎src-self-hosted/type.zig

+268
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
const builtin = @import("builtin");
2+
const Scope = @import("scope.zig").Scope;
3+
const Module = @import("module.zig").Module;
4+
const Value = @import("value.zig").Value;
5+
6+
pub const Type = struct {
7+
base: Value,
8+
id: Id,
9+
10+
pub const Id = builtin.TypeId;
11+
12+
pub fn destroy(base: *Type, module: *Module) void {
13+
switch (base.id) {
14+
Id.Struct => @fieldParentPtr(Struct, "base", base).destroy(module),
15+
Id.Fn => @fieldParentPtr(Fn, "base", base).destroy(module),
16+
Id.Type => @fieldParentPtr(MetaType, "base", base).destroy(module),
17+
Id.Void => @fieldParentPtr(Void, "base", base).destroy(module),
18+
Id.Bool => @fieldParentPtr(Bool, "base", base).destroy(module),
19+
Id.NoReturn => @fieldParentPtr(NoReturn, "base", base).destroy(module),
20+
Id.Int => @fieldParentPtr(Int, "base", base).destroy(module),
21+
Id.Float => @fieldParentPtr(Float, "base", base).destroy(module),
22+
Id.Pointer => @fieldParentPtr(Pointer, "base", base).destroy(module),
23+
Id.Array => @fieldParentPtr(Array, "base", base).destroy(module),
24+
Id.ComptimeFloat => @fieldParentPtr(ComptimeFloat, "base", base).destroy(module),
25+
Id.ComptimeInt => @fieldParentPtr(ComptimeInt, "base", base).destroy(module),
26+
Id.Undefined => @fieldParentPtr(Undefined, "base", base).destroy(module),
27+
Id.Null => @fieldParentPtr(Null, "base", base).destroy(module),
28+
Id.Optional => @fieldParentPtr(Optional, "base", base).destroy(module),
29+
Id.ErrorUnion => @fieldParentPtr(ErrorUnion, "base", base).destroy(module),
30+
Id.ErrorSet => @fieldParentPtr(ErrorSet, "base", base).destroy(module),
31+
Id.Enum => @fieldParentPtr(Enum, "base", base).destroy(module),
32+
Id.Union => @fieldParentPtr(Union, "base", base).destroy(module),
33+
Id.Namespace => @fieldParentPtr(Namespace, "base", base).destroy(module),
34+
Id.Block => @fieldParentPtr(Block, "base", base).destroy(module),
35+
Id.BoundFn => @fieldParentPtr(BoundFn, "base", base).destroy(module),
36+
Id.ArgTuple => @fieldParentPtr(ArgTuple, "base", base).destroy(module),
37+
Id.Opaque => @fieldParentPtr(Opaque, "base", base).destroy(module),
38+
Id.Promise => @fieldParentPtr(Promise, "base", base).destroy(module),
39+
}
40+
}
41+
42+
pub const Struct = struct {
43+
base: Type,
44+
decls: *Scope.Decls,
45+
46+
pub fn destroy(self: *Struct, module: *Module) void {
47+
module.a().destroy(self);
48+
}
49+
};
50+
51+
pub const Fn = struct {
52+
base: Type,
53+
54+
pub fn create(module: *Module) !*Fn {
55+
return module.a().create(Fn{
56+
.base = Type{
57+
.base = Value{
58+
.id = Value.Id.Type,
59+
.typeof = &MetaType.get(module).base,
60+
.ref_count = 1,
61+
},
62+
.id = builtin.TypeId.Fn,
63+
},
64+
});
65+
}
66+
67+
pub fn destroy(self: *Fn, module: *Module) void {
68+
module.a().destroy(self);
69+
}
70+
};
71+
72+
pub const MetaType = struct {
73+
base: Type,
74+
value: *Type,
75+
76+
/// Adds 1 reference to the resulting type
77+
pub fn get(module: *Module) *MetaType {
78+
module.meta_type.base.base.ref();
79+
return module.meta_type;
80+
}
81+
82+
pub fn destroy(self: *MetaType, module: *Module) void {
83+
module.a().destroy(self);
84+
}
85+
};
86+
87+
pub const Void = struct {
88+
base: Type,
89+
90+
/// Adds 1 reference to the resulting type
91+
pub fn get(module: *Module) *Void {
92+
module.void_type.base.base.ref();
93+
return module.void_type;
94+
}
95+
96+
pub fn destroy(self: *Void, module: *Module) void {
97+
module.a().destroy(self);
98+
}
99+
};
100+
101+
pub const Bool = struct {
102+
base: Type,
103+
104+
/// Adds 1 reference to the resulting type
105+
pub fn get(module: *Module) *Bool {
106+
module.bool_type.base.base.ref();
107+
return module.bool_type;
108+
}
109+
110+
pub fn destroy(self: *Bool, module: *Module) void {
111+
module.a().destroy(self);
112+
}
113+
};
114+
115+
pub const NoReturn = struct {
116+
base: Type,
117+
118+
/// Adds 1 reference to the resulting type
119+
pub fn get(module: *Module) *NoReturn {
120+
module.noreturn_type.base.base.ref();
121+
return module.noreturn_type;
122+
}
123+
124+
pub fn destroy(self: *NoReturn, module: *Module) void {
125+
module.a().destroy(self);
126+
}
127+
};
128+
129+
pub const Int = struct {
130+
base: Type,
131+
132+
pub fn destroy(self: *Int, module: *Module) void {
133+
module.a().destroy(self);
134+
}
135+
};
136+
137+
pub const Float = struct {
138+
base: Type,
139+
140+
pub fn destroy(self: *Float, module: *Module) void {
141+
module.a().destroy(self);
142+
}
143+
};
144+
pub const Pointer = struct {
145+
base: Type,
146+
147+
pub fn destroy(self: *Pointer, module: *Module) void {
148+
module.a().destroy(self);
149+
}
150+
};
151+
pub const Array = struct {
152+
base: Type,
153+
154+
pub fn destroy(self: *Array, module: *Module) void {
155+
module.a().destroy(self);
156+
}
157+
};
158+
pub const ComptimeFloat = struct {
159+
base: Type,
160+
161+
pub fn destroy(self: *ComptimeFloat, module: *Module) void {
162+
module.a().destroy(self);
163+
}
164+
};
165+
pub const ComptimeInt = struct {
166+
base: Type,
167+
168+
pub fn destroy(self: *ComptimeInt, module: *Module) void {
169+
module.a().destroy(self);
170+
}
171+
};
172+
pub const Undefined = struct {
173+
base: Type,
174+
175+
pub fn destroy(self: *Undefined, module: *Module) void {
176+
module.a().destroy(self);
177+
}
178+
};
179+
pub const Null = struct {
180+
base: Type,
181+
182+
pub fn destroy(self: *Null, module: *Module) void {
183+
module.a().destroy(self);
184+
}
185+
};
186+
pub const Optional = struct {
187+
base: Type,
188+
189+
pub fn destroy(self: *Optional, module: *Module) void {
190+
module.a().destroy(self);
191+
}
192+
};
193+
pub const ErrorUnion = struct {
194+
base: Type,
195+
196+
pub fn destroy(self: *ErrorUnion, module: *Module) void {
197+
module.a().destroy(self);
198+
}
199+
};
200+
pub const ErrorSet = struct {
201+
base: Type,
202+
203+
pub fn destroy(self: *ErrorSet, module: *Module) void {
204+
module.a().destroy(self);
205+
}
206+
};
207+
pub const Enum = struct {
208+
base: Type,
209+
210+
pub fn destroy(self: *Enum, module: *Module) void {
211+
module.a().destroy(self);
212+
}
213+
};
214+
pub const Union = struct {
215+
base: Type,
216+
217+
pub fn destroy(self: *Union, module: *Module) void {
218+
module.a().destroy(self);
219+
}
220+
};
221+
pub const Namespace = struct {
222+
base: Type,
223+
224+
pub fn destroy(self: *Namespace, module: *Module) void {
225+
module.a().destroy(self);
226+
}
227+
};
228+
229+
pub const Block = struct {
230+
base: Type,
231+
232+
pub fn destroy(self: *Block, module: *Module) void {
233+
module.a().destroy(self);
234+
}
235+
};
236+
237+
pub const BoundFn = struct {
238+
base: Type,
239+
240+
pub fn destroy(self: *BoundFn, module: *Module) void {
241+
module.a().destroy(self);
242+
}
243+
};
244+
245+
pub const ArgTuple = struct {
246+
base: Type,
247+
248+
pub fn destroy(self: *ArgTuple, module: *Module) void {
249+
module.a().destroy(self);
250+
}
251+
};
252+
253+
pub const Opaque = struct {
254+
base: Type,
255+
256+
pub fn destroy(self: *Opaque, module: *Module) void {
257+
module.a().destroy(self);
258+
}
259+
};
260+
261+
pub const Promise = struct {
262+
base: Type,
263+
264+
pub fn destroy(self: *Promise, module: *Module) void {
265+
module.a().destroy(self);
266+
}
267+
};
268+
};

‎src-self-hosted/value.zig

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
const std = @import("std");
2+
const builtin = @import("builtin");
3+
const Scope = @import("scope.zig").Scope;
4+
const Module = @import("module.zig").Module;
5+
6+
/// Values are ref-counted, heap-allocated, and copy-on-write
7+
/// If there is only 1 ref then write need not copy
8+
pub const Value = struct {
9+
id: Id,
10+
typeof: *Type,
11+
ref_count: usize,
12+
13+
pub fn ref(base: *Value) void {
14+
base.ref_count += 1;
15+
}
16+
17+
pub fn deref(base: *Value, module: *Module) void {
18+
base.ref_count -= 1;
19+
if (base.ref_count == 0) {
20+
base.typeof.base.deref(module);
21+
switch (base.id) {
22+
Id.Type => @fieldParentPtr(Type, "base", base).destroy(module),
23+
Id.Fn => @fieldParentPtr(Fn, "base", base).destroy(module),
24+
Id.Void => @fieldParentPtr(Void, "base", base).destroy(module),
25+
Id.Bool => @fieldParentPtr(Bool, "base", base).destroy(module),
26+
Id.NoReturn => @fieldParentPtr(NoReturn, "base", base).destroy(module),
27+
}
28+
}
29+
}
30+
31+
pub fn dump(base: *const Value) void {
32+
std.debug.warn("{}", @tagName(base.id));
33+
}
34+
35+
pub const Id = enum {
36+
Type,
37+
Fn,
38+
Void,
39+
Bool,
40+
NoReturn,
41+
};
42+
43+
pub const Type = @import("type.zig").Type;
44+
45+
pub const Fn = struct {
46+
base: Value,
47+
48+
/// parent should be the top level decls or container decls
49+
fndef_scope: *Scope.FnDef,
50+
51+
/// parent is scope for last parameter
52+
child_scope: *Scope,
53+
54+
/// parent is child_scope
55+
block_scope: *Scope.Block,
56+
57+
/// Creates a Fn value with 1 ref
58+
pub fn create(module: *Module, fn_type: *Type.Fn, fndef_scope: *Scope.FnDef) !*Fn {
59+
const self = try module.a().create(Fn{
60+
.base = Value{
61+
.id = Value.Id.Fn,
62+
.typeof = &fn_type.base,
63+
.ref_count = 1,
64+
},
65+
.fndef_scope = fndef_scope,
66+
.child_scope = &fndef_scope.base,
67+
.block_scope = undefined,
68+
});
69+
fn_type.base.base.ref();
70+
fndef_scope.fn_val = self;
71+
fndef_scope.base.ref();
72+
return self;
73+
}
74+
75+
pub fn destroy(self: *Fn, module: *Module) void {
76+
self.fndef_scope.base.deref(module);
77+
module.a().destroy(self);
78+
}
79+
};
80+
81+
pub const Void = struct {
82+
base: Value,
83+
84+
pub fn get(module: *Module) *Void {
85+
module.void_value.base.ref();
86+
return module.void_value;
87+
}
88+
89+
pub fn destroy(self: *Void, module: *Module) void {
90+
module.a().destroy(self);
91+
}
92+
};
93+
94+
pub const Bool = struct {
95+
base: Value,
96+
x: bool,
97+
98+
pub fn get(module: *Module, x: bool) *Bool {
99+
if (x) {
100+
module.true_value.base.ref();
101+
return module.true_value;
102+
} else {
103+
module.false_value.base.ref();
104+
return module.false_value;
105+
}
106+
}
107+
108+
pub fn destroy(self: *Bool, module: *Module) void {
109+
module.a().destroy(self);
110+
}
111+
};
112+
113+
pub const NoReturn = struct {
114+
base: Value,
115+
116+
pub fn get(module: *Module) *NoReturn {
117+
module.noreturn_value.base.ref();
118+
return module.noreturn_value;
119+
}
120+
121+
pub fn destroy(self: *NoReturn, module: *Module) void {
122+
module.a().destroy(self);
123+
}
124+
};
125+
};

‎src-self-hosted/visib.zig

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
pub const Visib = enum {
2+
Private,
3+
Pub,
4+
};

‎std/event/future.zig

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ test "std.event.Future" {
5757
const allocator = &da.allocator;
5858

5959
var loop: Loop = undefined;
60-
try loop.initSingleThreaded(allocator);
60+
try loop.initMultiThreaded(allocator);
6161
defer loop.deinit();
6262

6363
const handle = try async<allocator> testFuture(&loop);

‎std/zig/ast.zig

-6
Original file line numberDiff line numberDiff line change
@@ -970,14 +970,8 @@ pub const Node = struct {
970970
pub const Defer = struct {
971971
base: Node,
972972
defer_token: TokenIndex,
973-
kind: Kind,
974973
expr: *Node,
975974

976-
const Kind = enum {
977-
Error,
978-
Unconditional,
979-
};
980-
981975
pub fn iterate(self: *Defer, index: usize) ?*Node {
982976
var i = index;
983977

‎std/zig/parse.zig

-5
Original file line numberDiff line numberDiff line change
@@ -1041,11 +1041,6 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
10411041
const node = try arena.create(ast.Node.Defer{
10421042
.base = ast.Node{ .id = ast.Node.Id.Defer },
10431043
.defer_token = token_index,
1044-
.kind = switch (token_ptr.id) {
1045-
Token.Id.Keyword_defer => ast.Node.Defer.Kind.Unconditional,
1046-
Token.Id.Keyword_errdefer => ast.Node.Defer.Kind.Error,
1047-
else => unreachable,
1048-
},
10491044
.expr = undefined,
10501045
});
10511046
const node_ptr = try block.statements.addOne();

0 commit comments

Comments
 (0)
Please sign in to comment.