authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-18 20:09:29-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-18 20:09:29-07:00
log9010bd8aec612d5a14e4be800c80b72025fac2c5
treec286b41d6b9d3131539586d75a22b91301a1d23d
parent29daf10639149bd023db0be4e04eaf154dce0f83

stage2: astgen: fix most of the remaining compile errors

more progress on converting astgen to the new AST memory layout. only a few code paths left to update.

7 files changed, 1052 insertions(+), 823 deletions(-)

lib/std/zig/ast.zig+10-30
......@@ -1754,25 +1754,20 @@ pub const Tree = struct {
17541754 const token_tags = tree.tokens.items(.tag);
17551755 // TODO: looks like stage1 isn't quite smart enough to handle enum
17561756 // literals in some places here
1757 const Kind = full.PtrType.Kind;
1758 const kind: Kind = switch (token_tags[info.main_token]) {
1757 const Size = std.builtin.TypeInfo.Pointer.Size;
1758 const size: Size = switch (token_tags[info.main_token]) {
17591759 .asterisk,
17601760 .asterisk_asterisk,
17611761 => switch (token_tags[info.main_token + 1]) {
1762 .r_bracket => .many,
1763 .colon => .sentinel,
1764 .identifier => if (token_tags[info.main_token - 1] == .l_bracket) Kind.c else .one,
1765 else => .one,
1766 },
1767 .l_bracket => switch (token_tags[info.main_token + 1]) {
1768 .r_bracket => Kind.slice,
1769 .colon => .slice_sentinel,
1770 else => unreachable,
1762 .r_bracket, .colon => .Many,
1763 .identifier => if (token_tags[info.main_token - 1] == .l_bracket) Size.C else .One,
1764 else => .One,
17711765 },
1766 .l_bracket => Size.Slice,
17721767 else => unreachable,
17731768 };
17741769 var result: full.PtrType = .{
1775 .kind = kind,
1770 .size = size,
17761771 .allowzero_token = null,
17771772 .const_token = null,
17781773 .volatile_token = null,
......@@ -1782,13 +1777,7 @@ pub const Tree = struct {
17821777 // here while looking for modifiers as that could result in false
17831778 // positives. Therefore, start after a sentinel if there is one and
17841779 // skip over any align node and bit range nodes.
1785 var i = if (kind == .sentinel or kind == .slice_sentinel) blk: {
1786 assert(info.sentinel != 0);
1787 break :blk tree.lastToken(info.sentinel) + 1;
1788 } else blk: {
1789 assert(info.sentinel == 0);
1790 break :blk info.main_token;
1791 };
1780 var i = if (info.sentinel != 0) tree.lastToken(info.sentinel) + 1 else info.main_token;
17921781 const end = tree.firstToken(info.child_type);
17931782 while (i < end) : (i += 1) {
17941783 switch (token_tags[i]) {
......@@ -2115,7 +2104,7 @@ pub const full = struct {
21152104 .comptime_noalias = comptime_noalias,
21162105 .name_token = name_token,
21172106 .anytype_ellipsis3 = it.tok_i - 1,
2118 .type_expr = param_type,
2107 .type_expr = 0,
21192108 };
21202109 }
21212110 it.tok_flag = false;
......@@ -2166,21 +2155,12 @@ pub const full = struct {
21662155 };
21672156
21682157 pub const PtrType = struct {
2169 kind: Kind,
2158 size: std.builtin.TypeInfo.Pointer.Size,
21702159 allowzero_token: ?TokenIndex,
21712160 const_token: ?TokenIndex,
21722161 volatile_token: ?TokenIndex,
21732162 ast: Ast,
21742163
2175 pub const Kind = enum {
2176 one,
2177 many,
2178 sentinel,
2179 c,
2180 slice,
2181 slice_sentinel,
2182 };
2183
21842164 pub const Ast = struct {
21852165 main_token: TokenIndex,
21862166 align_node: Node.Index,
lib/std/zig/render.zig+25-23
......@@ -677,8 +677,8 @@ fn renderPtrType(
677677 ptr_type: ast.full.PtrType,
678678 space: Space,
679679) Error!void {
680 switch (ptr_type.kind) {
681 .one => {
680 switch (ptr_type.size) {
681 .One => {
682682 // Since ** tokens exist and the same token is shared by two
683683 // nested pointer types, we check to see if we are the parent
684684 // in such a relationship. If so, skip rendering anything for
......@@ -691,33 +691,35 @@ fn renderPtrType(
691691 }
692692 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // asterisk
693693 },
694 .many => {
695 try renderToken(ais, tree, ptr_type.ast.main_token - 1, .none); // lbracket
696 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // asterisk
697 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // rbracket
698 },
699 .sentinel => {
700 try renderToken(ais, tree, ptr_type.ast.main_token - 1, .none); // lbracket
701 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // asterisk
702 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // colon
703 try renderExpression(ais, tree, ptr_type.ast.sentinel, .none);
704 try renderToken(ais, tree, tree.lastToken(ptr_type.ast.sentinel) + 1, .none); // rbracket
694 .Many => {
695 if (ptr_type.ast.sentinel == 0) {
696 try renderToken(ais, tree, ptr_type.ast.main_token - 1, .none); // lbracket
697 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // asterisk
698 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // rbracket
699 } else {
700 try renderToken(ais, tree, ptr_type.ast.main_token - 1, .none); // lbracket
701 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // asterisk
702 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // colon
703 try renderExpression(ais, tree, ptr_type.ast.sentinel, .none);
704 try renderToken(ais, tree, tree.lastToken(ptr_type.ast.sentinel) + 1, .none); // rbracket
705 }
705706 },
706 .c => {
707 .C => {
707708 try renderToken(ais, tree, ptr_type.ast.main_token - 1, .none); // lbracket
708709 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // asterisk
709710 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // c
710711 try renderToken(ais, tree, ptr_type.ast.main_token + 2, .none); // rbracket
711712 },
712 .slice => {
713 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // lbracket
714 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // rbracket
715 },
716 .slice_sentinel => {
717 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // lbracket
718 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // colon
719 try renderExpression(ais, tree, ptr_type.ast.sentinel, .none);
720 try renderToken(ais, tree, tree.lastToken(ptr_type.ast.sentinel) + 1, .none); // rbracket
713 .Slice => {
714 if (ptr_type.ast.sentinel == 0) {
715 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // lbracket
716 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // rbracket
717 } else {
718 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // lbracket
719 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // colon
720 try renderExpression(ais, tree, ptr_type.ast.sentinel, .none);
721 try renderToken(ais, tree, tree.lastToken(ptr_type.ast.sentinel) + 1, .none); // rbracket
722 }
721723 },
722724 }
723725
src/BuiltinFn.zig+523-520
......@@ -115,727 +115,730 @@ allows_lvalue: bool = false,
115115/// of parameters.
116116param_count: ?u8,
117117
118pub const list = std.ComptimeStringMap(@This(), .{
119 .{
120 "@addWithOverflow",
118pub const list = list: {
119 @setEvalBranchQuota(3000);
120 break :list std.ComptimeStringMap(@This(), .{
121121 .{
122 .tag = .add_with_overflow,
123 .param_count = 4,
122 "@addWithOverflow",
123 .{
124 .tag = .add_with_overflow,
125 .param_count = 4,
126 },
124127 },
125 },
126 .{
127 "@alignCast",
128128 .{
129 .tag = align_cast,
130 .param_count = 1,
129 "@alignCast",
130 .{
131 .tag = .align_cast,
132 .param_count = 1,
133 },
131134 },
132 },
133 .{
134 "@alignOf",
135135 .{
136 .tag = .align_of,
137 .param_count = 1,
136 "@alignOf",
137 .{
138 .tag = .align_of,
139 .param_count = 1,
140 },
138141 },
139 },
140 .{
141 "@as",
142142 .{
143 .tag = .as,
144 .needs_mem_loc = true,
145 .param_count = 2,
143 "@as",
144 .{
145 .tag = .as,
146 .needs_mem_loc = true,
147 .param_count = 2,
148 },
146149 },
147 },
148 .{
149 "@asyncCall",
150150 .{
151 .tag = .async_call,
152 .param_count = null,
151 "@asyncCall",
152 .{
153 .tag = .async_call,
154 .param_count = null,
155 },
153156 },
154 },
155 .{
156 "@atomicLoad",
157157 .{
158 .tag = .atomic_load,
159 .param_count = 3,
158 "@atomicLoad",
159 .{
160 .tag = .atomic_load,
161 .param_count = 3,
162 },
160163 },
161 },
162 .{
163 "@atomicRmw",
164164 .{
165 .tag = .atomic_rmw,
166 .param_count = 5,
165 "@atomicRmw",
166 .{
167 .tag = .atomic_rmw,
168 .param_count = 5,
169 },
167170 },
168 },
169 .{
170 "@atomicStore",
171171 .{
172 .tag = .atomic_store,
173 .param_count = 4,
172 "@atomicStore",
173 .{
174 .tag = .atomic_store,
175 .param_count = 4,
176 },
174177 },
175 },
176 .{
177 "@bitCast",
178178 .{
179 .tag = .bit_cast,
180 .needs_mem_loc = true,
181 .param_count = 2,
179 "@bitCast",
180 .{
181 .tag = .bit_cast,
182 .needs_mem_loc = true,
183 .param_count = 2,
184 },
182185 },
183 },
184 .{
185 "@bitOffsetOf",
186186 .{
187 .tag = .bit_offset_of,
188 .param_count = 2,
187 "@bitOffsetOf",
188 .{
189 .tag = .bit_offset_of,
190 .param_count = 2,
191 },
189192 },
190 },
191 .{
192 "@boolToInt",
193193 .{
194 .tag = .bool_to_int,
195 .param_count = 1,
194 "@boolToInt",
195 .{
196 .tag = .bool_to_int,
197 .param_count = 1,
198 },
196199 },
197 },
198 .{
199 "@bitSizeOf",
200200 .{
201 .tag = .bit_size_of,
202 .param_count = 1,
201 "@bitSizeOf",
202 .{
203 .tag = .bit_size_of,
204 .param_count = 1,
205 },
203206 },
204 },
205 .{
206 "@breakpoint",
207207 .{
208 .tag = .breakpoint,
209 .param_count = 0,
208 "@breakpoint",
209 .{
210 .tag = .breakpoint,
211 .param_count = 0,
212 },
210213 },
211 },
212 .{
213 "@mulAdd",
214214 .{
215 .tag = .mul_add,
216 .param_count = 4,
215 "@mulAdd",
216 .{
217 .tag = .mul_add,
218 .param_count = 4,
219 },
217220 },
218 },
219 .{
220 "@byteSwap",
221221 .{
222 .tag = .byte_swap,
223 .param_count = 2,
222 "@byteSwap",
223 .{
224 .tag = .byte_swap,
225 .param_count = 2,
226 },
224227 },
225 },
226 .{
227 "@bitReverse",
228228 .{
229 .tag = .bit_reverse,
230 .param_count = 2,
229 "@bitReverse",
230 .{
231 .tag = .bit_reverse,
232 .param_count = 2,
233 },
231234 },
232 },
233 .{
234 "@byteOffsetOf",
235235 .{
236 .tag = .byte_offset_of,
237 .param_count = 2,
236 "@byteOffsetOf",
237 .{
238 .tag = .byte_offset_of,
239 .param_count = 2,
240 },
238241 },
239 },
240 .{
241 "@call",
242242 .{
243 .tag = .call,
244 .needs_mem_loc = true,
245 .param_count = 3,
243 "@call",
244 .{
245 .tag = .call,
246 .needs_mem_loc = true,
247 .param_count = 3,
248 },
246249 },
247 },
248 .{
249 "@cDefine",
250250 .{
251 .tag = .c_define,
252 .param_count = 2,
251 "@cDefine",
252 .{
253 .tag = .c_define,
254 .param_count = 2,
255 },
253256 },
254 },
255 .{
256 "@cImport",
257257 .{
258 .tag = .c_import,
259 .param_count = 1,
258 "@cImport",
259 .{
260 .tag = .c_import,
261 .param_count = 1,
262 },
260263 },
261 },
262 .{
263 "@cInclude",
264264 .{
265 .tag = .c_include,
266 .param_count = 1,
265 "@cInclude",
266 .{
267 .tag = .c_include,
268 .param_count = 1,
269 },
267270 },
268 },
269 .{
270 "@clz",
271271 .{
272 .tag = .clz,
273 .param_count = 2,
272 "@clz",
273 .{
274 .tag = .clz,
275 .param_count = 2,
276 },
274277 },
275 },
276 .{
277 "@cmpxchgStrong",
278278 .{
279 .tag = .cmpxchg_strong,
280 .param_count = 6,
279 "@cmpxchgStrong",
280 .{
281 .tag = .cmpxchg_strong,
282 .param_count = 6,
283 },
281284 },
282 },
283 .{
284 "@cmpxchgWeak",
285285 .{
286 .tag = .cmpxchg_weak,
287 .param_count = 6,
286 "@cmpxchgWeak",
287 .{
288 .tag = .cmpxchg_weak,
289 .param_count = 6,
290 },
288291 },
289 },
290 .{
291 "@compileError",
292292 .{
293 .tag = .compile_error,
294 .param_count = 1,
293 "@compileError",
294 .{
295 .tag = .compile_error,
296 .param_count = 1,
297 },
295298 },
296 },
297 .{
298 "@compileLog",
299299 .{
300 .tag = .compile_log,
301 .param_count = null,
300 "@compileLog",
301 .{
302 .tag = .compile_log,
303 .param_count = null,
304 },
302305 },
303 },
304 .{
305 "@ctz",
306306 .{
307 .tag = .ctz,
308 .param_count = 2,
307 "@ctz",
308 .{
309 .tag = .ctz,
310 .param_count = 2,
311 },
309312 },
310 },
311 .{
312 "@cUndef",
313313 .{
314 .tag = .c_undef,
315 .param_count = 1,
314 "@cUndef",
315 .{
316 .tag = .c_undef,
317 .param_count = 1,
318 },
316319 },
317 },
318 .{
319 "@divExact",
320320 .{
321 .tag = .div_exact,
322 .param_count = 2,
321 "@divExact",
322 .{
323 .tag = .div_exact,
324 .param_count = 2,
325 },
323326 },
324 },
325 .{
326 "@divFloor",
327327 .{
328 .tag = .div_floor,
329 .param_count = 2,
328 "@divFloor",
329 .{
330 .tag = .div_floor,
331 .param_count = 2,
332 },
330333 },
331 },
332 .{
333 "@divTrunc",
334334 .{
335 .tag = .div_trunc,
336 .param_count = 2,
335 "@divTrunc",
336 .{
337 .tag = .div_trunc,
338 .param_count = 2,
339 },
337340 },
338 },
339 .{
340 "@embedFile",
341341 .{
342 .tag = .embed_file,
343 .param_count = 1,
342 "@embedFile",
343 .{
344 .tag = .embed_file,
345 .param_count = 1,
346 },
344347 },
345 },
346 .{
347 "@enumToInt",
348348 .{
349 .tag = .enum_to_int,
350 .param_count = 1,
349 "@enumToInt",
350 .{
351 .tag = .enum_to_int,
352 .param_count = 1,
353 },
351354 },
352 },
353 .{
354 "@errorName",
355355 .{
356 .tag = .error_name,
357 .param_count = 1,
356 "@errorName",
357 .{
358 .tag = .error_name,
359 .param_count = 1,
360 },
358361 },
359 },
360 .{
361 "@errorReturnTrace",
362362 .{
363 .tag = .error_return_trace,
364 .param_count = 0,
363 "@errorReturnTrace",
364 .{
365 .tag = .error_return_trace,
366 .param_count = 0,
367 },
365368 },
366 },
367 .{
368 "@errorToInt",
369369 .{
370 .tag = .error_to_int,
371 .param_count = 1,
370 "@errorToInt",
371 .{
372 .tag = .error_to_int,
373 .param_count = 1,
374 },
372375 },
373 },
374 .{
375 "@errSetCast",
376376 .{
377 .tag = .err_set_cast,
378 .param_count = 2,
377 "@errSetCast",
378 .{
379 .tag = .err_set_cast,
380 .param_count = 2,
381 },
379382 },
380 },
381 .{
382 "@export",
383383 .{
384 .tag = .@"export",
385 .param_count = 2,
384 "@export",
385 .{
386 .tag = .@"export",
387 .param_count = 2,
388 },
386389 },
387 },
388 .{
389 "@fence",
390390 .{
391 .tag = .fence,
392 .param_count = 0,
391 "@fence",
392 .{
393 .tag = .fence,
394 .param_count = 0,
395 },
393396 },
394 },
395 .{
396 "@field",
397397 .{
398 .tag = .field,
399 .needs_mem_loc = true,
400 .param_count = 2,
401 .allows_lvalue = true,
398 "@field",
399 .{
400 .tag = .field,
401 .needs_mem_loc = true,
402 .param_count = 2,
403 .allows_lvalue = true,
404 },
402405 },
403 },
404 .{
405 "@fieldParentPtr",
406406 .{
407 .tag = .field_parent_ptr,
408 .param_count = 3,
407 "@fieldParentPtr",
408 .{
409 .tag = .field_parent_ptr,
410 .param_count = 3,
411 },
409412 },
410 },
411 .{
412 "@floatCast",
413413 .{
414 .tag = .float_cast,
415 .param_count = 1,
414 "@floatCast",
415 .{
416 .tag = .float_cast,
417 .param_count = 1,
418 },
416419 },
417 },
418 .{
419 "@floatToInt",
420420 .{
421 .tag = .float_to_int,
422 .param_count = 1,
421 "@floatToInt",
422 .{
423 .tag = .float_to_int,
424 .param_count = 1,
425 },
423426 },
424 },
425 .{
426 "@frame",
427427 .{
428 .tag = .frame,
429 .param_count = 0,
428 "@frame",
429 .{
430 .tag = .frame,
431 .param_count = 0,
432 },
430433 },
431 },
432 .{
433 "@Frame",
434434 .{
435 .tag = .Frame,
436 .param_count = 1,
435 "@Frame",
436 .{
437 .tag = .Frame,
438 .param_count = 1,
439 },
437440 },
438 },
439 .{
440 "@frameAddress",
441441 .{
442 .tag = .frame_address,
443 .param_count = 0,
442 "@frameAddress",
443 .{
444 .tag = .frame_address,
445 .param_count = 0,
446 },
444447 },
445 },
446 .{
447 "@frameSize",
448448 .{
449 .tag = .frame_size,
450 .param_count = 1,
449 "@frameSize",
450 .{
451 .tag = .frame_size,
452 .param_count = 1,
453 },
451454 },
452 },
453 .{
454 "@hasDecl",
455455 .{
456 .tag = .has_decl,
457 .param_count = 2,
456 "@hasDecl",
457 .{
458 .tag = .has_decl,
459 .param_count = 2,
460 },
458461 },
459 },
460 .{
461 "@hasField",
462462 .{
463 .tag = .has_field,
464 .param_count = 2,
463 "@hasField",
464 .{
465 .tag = .has_field,
466 .param_count = 2,
467 },
465468 },
466 },
467 .{
468 "@import",
469469 .{
470 .tag = .import,
471 .param_count = 1,
470 "@import",
471 .{
472 .tag = .import,
473 .param_count = 1,
474 },
472475 },
473 },
474 .{
475 "@intCast",
476476 .{
477 .tag = .int_cast,
478 .param_count = 1,
477 "@intCast",
478 .{
479 .tag = .int_cast,
480 .param_count = 1,
481 },
479482 },
480 },
481 .{
482 "@intToEnum",
483483 .{
484 .tag = .int_to_enum,
485 .param_count = 1,
484 "@intToEnum",
485 .{
486 .tag = .int_to_enum,
487 .param_count = 1,
488 },
486489 },
487 },
488 .{
489 "@intToError",
490490 .{
491 .tag = .int_to_error,
492 .param_count = 1,
491 "@intToError",
492 .{
493 .tag = .int_to_error,
494 .param_count = 1,
495 },
493496 },
494 },
495 .{
496 "@intToFloat",
497497 .{
498 .tag = .int_to_float,
499 .param_count = 1,
498 "@intToFloat",
499 .{
500 .tag = .int_to_float,
501 .param_count = 1,
502 },
500503 },
501 },
502 .{
503 "@intToPtr",
504504 .{
505 .tag = .int_to_ptr,
506 .param_count = 2,
505 "@intToPtr",
506 .{
507 .tag = .int_to_ptr,
508 .param_count = 2,
509 },
507510 },
508 },
509 .{
510 "@memcpy",
511511 .{
512 .tag = .memcpy,
513 .param_count = 3,
512 "@memcpy",
513 .{
514 .tag = .memcpy,
515 .param_count = 3,
516 },
514517 },
515 },
516 .{
517 "@memset",
518518 .{
519 .tag = .memset,
520 .param_count = 3,
519 "@memset",
520 .{
521 .tag = .memset,
522 .param_count = 3,
523 },
521524 },
522 },
523 .{
524 "@wasmMemorySize",
525525 .{
526 .tag = .wasm_memory_size,
527 .param_count = 1,
526 "@wasmMemorySize",
527 .{
528 .tag = .wasm_memory_size,
529 .param_count = 1,
530 },
528531 },
529 },
530 .{
531 "@wasmMemoryGrow",
532532 .{
533 .tag = .wasm_memory_grow,
534 .param_count = 2,
533 "@wasmMemoryGrow",
534 .{
535 .tag = .wasm_memory_grow,
536 .param_count = 2,
537 },
535538 },
536 },
537 .{
538 "@mod",
539539 .{
540 .tag = .mod,
541 .param_count = 2,
540 "@mod",
541 .{
542 .tag = .mod,
543 .param_count = 2,
544 },
542545 },
543 },
544 .{
545 "@mulWithOverflow",
546546 .{
547 .tag = .mul_with_overflow,
548 .param_count = 4,
547 "@mulWithOverflow",
548 .{
549 .tag = .mul_with_overflow,
550 .param_count = 4,
551 },
549552 },
550 },
551 .{
552 "@panic",
553553 .{
554 .tag = .panic,
555 .param_count = 1,
554 "@panic",
555 .{
556 .tag = .panic,
557 .param_count = 1,
558 },
556559 },
557 },
558 .{
559 "@popCount",
560560 .{
561 .tag = .pop_count,
562 .param_count = 2,
561 "@popCount",
562 .{
563 .tag = .pop_count,
564 .param_count = 2,
565 },
563566 },
564 },
565 .{
566 "@ptrCast",
567567 .{
568 .tag = .ptr_cast,
569 .param_count = 2,
568 "@ptrCast",
569 .{
570 .tag = .ptr_cast,
571 .param_count = 2,
572 },
570573 },
571 },
572 .{
573 "@ptrToInt",
574574 .{
575 .tag = .ptr_to_int,
576 .param_count = 1,
575 "@ptrToInt",
576 .{
577 .tag = .ptr_to_int,
578 .param_count = 1,
579 },
577580 },
578 },
579 .{
580 "@rem",
581581 .{
582 .tag = .rem,
583 .param_count = 2,
582 "@rem",
583 .{
584 .tag = .rem,
585 .param_count = 2,
586 },
584587 },
585 },
586 .{
587 "@returnAddress",
588588 .{
589 .tag = .return_address,
590 .param_count = 0,
589 "@returnAddress",
590 .{
591 .tag = .return_address,
592 .param_count = 0,
593 },
591594 },
592 },
593 .{
594 "@setAlignStack",
595595 .{
596 .tag = .set_align_stack,
597 .param_count = 1,
596 "@setAlignStack",
597 .{
598 .tag = .set_align_stack,
599 .param_count = 1,
600 },
598601 },
599 },
600 .{
601 "@setCold",
602602 .{
603 .tag = .set_cold,
604 .param_count = 1,
603 "@setCold",
604 .{
605 .tag = .set_cold,
606 .param_count = 1,
607 },
605608 },
606 },
607 .{
608 "@setEvalBranchQuota",
609609 .{
610 .tag = .set_eval_branch_quota,
611 .param_count = 1,
610 "@setEvalBranchQuota",
611 .{
612 .tag = .set_eval_branch_quota,
613 .param_count = 1,
614 },
612615 },
613 },
614 .{
615 "@setFloatMode",
616616 .{
617 .tag = .set_float_mode,
618 .param_count = 1,
617 "@setFloatMode",
618 .{
619 .tag = .set_float_mode,
620 .param_count = 1,
621 },
619622 },
620 },
621 .{
622 "@setRuntimeSafety",
623623 .{
624 .tag = .set_runtime_safety,
625 .param_count = 1,
624 "@setRuntimeSafety",
625 .{
626 .tag = .set_runtime_safety,
627 .param_count = 1,
628 },
626629 },
627 },
628 .{
629 "@shlExact",
630630 .{
631 .tag = .shl_exact,
632 .param_count = 2,
631 "@shlExact",
632 .{
633 .tag = .shl_exact,
634 .param_count = 2,
635 },
633636 },
634 },
635 .{
636 "@shlWithOverflow",
637637 .{
638 .tag = .shl_with_overflow,
639 .param_count = 4,
638 "@shlWithOverflow",
639 .{
640 .tag = .shl_with_overflow,
641 .param_count = 4,
642 },
640643 },
641 },
642 .{
643 "@shrExact",
644644 .{
645 .tag = .shr_exact,
646 .param_count = 2,
645 "@shrExact",
646 .{
647 .tag = .shr_exact,
648 .param_count = 2,
649 },
647650 },
648 },
649 .{
650 "@shuffle",
651651 .{
652 .tag = .shuffle,
653 .param_count = 4,
652 "@shuffle",
653 .{
654 .tag = .shuffle,
655 .param_count = 4,
656 },
654657 },
655 },
656 .{
657 "@sizeOf",
658658 .{
659 .tag = .size_of,
660 .param_count = 1,
659 "@sizeOf",
660 .{
661 .tag = .size_of,
662 .param_count = 1,
663 },
661664 },
662 },
663 .{
664 "@splat",
665665 .{
666 .tag = .splat,
667 .needs_mem_loc = true,
668 .param_count = 2,
666 "@splat",
667 .{
668 .tag = .splat,
669 .needs_mem_loc = true,
670 .param_count = 2,
671 },
669672 },
670 },
671 .{
672 "@reduce",
673673 .{
674 .tag = .reduce,
675 .param_count = 2,
674 "@reduce",
675 .{
676 .tag = .reduce,
677 .param_count = 2,
678 },
676679 },
677 },
678 .{
679 "@src",
680680 .{
681 .tag = .src,
682 .needs_mem_loc = true,
683 .param_count = 0,
681 "@src",
682 .{
683 .tag = .src,
684 .needs_mem_loc = true,
685 .param_count = 0,
686 },
684687 },
685 },
686 .{
687 "@sqrt",
688688 .{
689 .tag = .sqrt,
690 .param_count = 1,
689 "@sqrt",
690 .{
691 .tag = .sqrt,
692 .param_count = 1,
693 },
691694 },
692 },
693 .{
694 "@sin",
695695 .{
696 .tag = .sin,
697 .param_count = 1,
696 "@sin",
697 .{
698 .tag = .sin,
699 .param_count = 1,
700 },
698701 },
699 },
700 .{
701 "@cos",
702702 .{
703 .tag = .cos,
704 .param_count = 1,
703 "@cos",
704 .{
705 .tag = .cos,
706 .param_count = 1,
707 },
705708 },
706 },
707 .{
708 "@exp",
709709 .{
710 .tag = .exp,
711 .param_count = 1,
710 "@exp",
711 .{
712 .tag = .exp,
713 .param_count = 1,
714 },
712715 },
713 },
714 .{
715 "@exp2",
716716 .{
717 .tag = .exp2,
718 .param_count = 1,
717 "@exp2",
718 .{
719 .tag = .exp2,
720 .param_count = 1,
721 },
719722 },
720 },
721 .{
722 "@log",
723723 .{
724 .tag = .log,
725 .param_count = 1,
724 "@log",
725 .{
726 .tag = .log,
727 .param_count = 1,
728 },
726729 },
727 },
728 .{
729 "@log2",
730730 .{
731 .tag = .log2,
732 .param_count = 1,
731 "@log2",
732 .{
733 .tag = .log2,
734 .param_count = 1,
735 },
733736 },
734 },
735 .{
736 "@log10",
737737 .{
738 .tag = .log10,
739 .param_count = 1,
738 "@log10",
739 .{
740 .tag = .log10,
741 .param_count = 1,
742 },
740743 },
741 },
742 .{
743 "@fabs",
744744 .{
745 .tag = .fabs,
746 .param_count = 1,
745 "@fabs",
746 .{
747 .tag = .fabs,
748 .param_count = 1,
749 },
747750 },
748 },
749 .{
750 "@floor",
751751 .{
752 .tag = .floor,
753 .param_count = 1,
752 "@floor",
753 .{
754 .tag = .floor,
755 .param_count = 1,
756 },
754757 },
755 },
756 .{
757 "@ceil",
758758 .{
759 .tag = .ceil,
760 .param_count = 1,
759 "@ceil",
760 .{
761 .tag = .ceil,
762 .param_count = 1,
763 },
761764 },
762 },
763 .{
764 "@trunc",
765765 .{
766 .tag = .trunc,
767 .param_count = 1,
766 "@trunc",
767 .{
768 .tag = .trunc,
769 .param_count = 1,
770 },
768771 },
769 },
770 .{
771 "@round",
772772 .{
773 .tag = .round,
774 .param_count = 1,
773 "@round",
774 .{
775 .tag = .round,
776 .param_count = 1,
777 },
775778 },
776 },
777 .{
778 "@subWithOverflow",
779779 .{
780 .tag = .sub_with_overflow,
781 .param_count = 4,
780 "@subWithOverflow",
781 .{
782 .tag = .sub_with_overflow,
783 .param_count = 4,
784 },
782785 },
783 },
784 .{
785 "@tagName",
786786 .{
787 .tag = .tag_name,
788 .param_count = 1,
787 "@tagName",
788 .{
789 .tag = .tag_name,
790 .param_count = 1,
791 },
789792 },
790 },
791 .{
792 "@This",
793793 .{
794 .tag = .This,
795 .param_count = 0,
794 "@This",
795 .{
796 .tag = .This,
797 .param_count = 0,
798 },
796799 },
797 },
798 .{
799 "@truncate",
800800 .{
801 .tag = .truncate,
802 .param_count = 2,
801 "@truncate",
802 .{
803 .tag = .truncate,
804 .param_count = 2,
805 },
803806 },
804 },
805 .{
806 "@Type",
807807 .{
808 .tag = .Type,
809 .param_count = 1,
808 "@Type",
809 .{
810 .tag = .Type,
811 .param_count = 1,
812 },
810813 },
811 },
812 .{
813 "@typeInfo",
814814 .{
815 .tag = .type_info,
816 .param_count = 1,
815 "@typeInfo",
816 .{
817 .tag = .type_info,
818 .param_count = 1,
819 },
817820 },
818 },
819 .{
820 "@typeName",
821821 .{
822 .tag = .type_name,
823 .param_count = 1,
822 "@typeName",
823 .{
824 .tag = .type_name,
825 .param_count = 1,
826 },
824827 },
825 },
826 .{
827 "@TypeOf",
828828 .{
829 .tag = .TypeOf,
830 .param_count = null,
829 "@TypeOf",
830 .{
831 .tag = .TypeOf,
832 .param_count = null,
833 },
831834 },
832 },
833 .{
834 "@unionInit",
835835 .{
836 .tag = .union_init,
837 .needs_mem_loc = true,
838 .param_count = 3,
836 "@unionInit",
837 .{
838 .tag = .union_init,
839 .needs_mem_loc = true,
840 .param_count = 3,
841 },
839842 },
840 },
841});
843 });
844};
src/Module.zig+9-8
......@@ -430,12 +430,12 @@ pub const Scope = struct {
430430 /// Asserts the scope is a child of a File and has an AST tree and returns the tree.
431431 pub fn tree(self: *Scope) *const ast.Tree {
432432 switch (self.tag) {
433 .file => return self.cast(File).?.tree,
434 .block => return self.cast(Block).?.src_decl.container.file_scope.tree,
435 .gen_zir => return self.cast(GenZIR).?.decl.container.file_scope.tree,
436 .local_val => return self.cast(LocalVal).?.gen_zir.decl.container.file_scope.tree,
437 .local_ptr => return self.cast(LocalPtr).?.gen_zir.decl.container.file_scope.tree,
438 .container => return self.cast(Container).?.file_scope.tree,
433 .file => return &self.cast(File).?.tree,
434 .block => return &self.cast(Block).?.src_decl.container.file_scope.tree,
435 .gen_zir => return &self.cast(GenZIR).?.decl.container.file_scope.tree,
436 .local_val => return &self.cast(LocalVal).?.gen_zir.decl.container.file_scope.tree,
437 .local_ptr => return &self.cast(LocalPtr).?.gen_zir.decl.container.file_scope.tree,
438 .container => return &self.cast(Container).?.file_scope.tree,
439439 }
440440 }
441441
......@@ -1612,6 +1612,7 @@ fn astgenAndSemaVarDecl(
16121612 .decl = decl,
16131613 .arena = &type_scope_arena.allocator,
16141614 .parent = &decl.container.base,
1615 .force_comptime = true,
16151616 };
16161617 defer type_scope.instructions.deinit(mod.gpa);
16171618
......@@ -1630,7 +1631,7 @@ fn astgenAndSemaVarDecl(
16301631 } else {
16311632 return mod.failTok(
16321633 &block_scope.base,
1633 tree.firstToken(var_decl),
1634 var_decl.ast.mut_token,
16341635 "unable to infer variable type",
16351636 .{},
16361637 );
......@@ -1639,7 +1640,7 @@ fn astgenAndSemaVarDecl(
16391640 if (is_mutable and !var_info.ty.isValidVarType(is_extern)) {
16401641 return mod.failTok(
16411642 &block_scope.base,
1642 tree.firstToken(var_decl),
1643 var_decl.ast.mut_token,
16431644 "variable of type '{}' must be const",
16441645 .{var_info.ty},
16451646 );
src/astgen.zig+473-226
......@@ -59,6 +59,8 @@ pub const ResultLoc = union(enum) {
5959
6060pub fn typeExpr(mod: *Module, scope: *Scope, type_node: ast.Node.Index) InnerError!*zir.Inst {
6161 const tree = scope.tree();
62 const token_starts = tree.tokens.items(.start);
63
6264 const type_src = token_starts[tree.firstToken(type_node)];
6365 const type_type = try addZIRInstConst(mod, scope, type_src, .{
6466 .ty = Type.initTag(.type),
......@@ -76,13 +78,17 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.I
7678 .root => unreachable,
7779 .@"usingnamespace" => unreachable,
7880 .test_decl => unreachable,
79 .doc_comment => unreachable,
80 .var_decl => unreachable,
81 .global_var_decl => unreachable,
82 .local_var_decl => unreachable,
83 .simple_var_decl => unreachable,
84 .aligned_var_decl => unreachable,
8185 .switch_case => unreachable,
82 .switch_else => unreachable,
86 .switch_case_one => unreachable,
8387 .container_field_init => unreachable,
8488 .container_field_align => unreachable,
8589 .container_field => unreachable,
90 .asm_output => unreachable,
91 .asm_input => unreachable,
8692
8793 .assign,
8894 .assign_bit_and,
......@@ -122,58 +128,107 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.I
122128 .bool_and,
123129 .bool_or,
124130 .@"asm",
131 .asm_simple,
125132 .string_literal,
126133 .integer_literal,
127134 .call,
128 .@"unreachable",
135 .call_comma,
136 .async_call,
137 .async_call_comma,
138 .call_one,
139 .call_one_comma,
140 .async_call_one,
141 .async_call_one_comma,
142 .unreachable_literal,
129143 .@"return",
130144 .@"if",
145 .if_simple,
131146 .@"while",
147 .while_simple,
148 .while_cont,
132149 .bool_not,
133150 .address_of,
134151 .float_literal,
135152 .undefined_literal,
136 .bool_literal,
153 .true_literal,
154 .false_literal,
137155 .null_literal,
138156 .optional_type,
139157 .block,
140 .labeled_block,
158 .block_semicolon,
159 .block_two,
160 .block_two_semicolon,
141161 .@"break",
142 .PtrType,
162 .ptr_type_aligned,
163 .ptr_type_sentinel,
164 .ptr_type,
165 .ptr_type_bit_range,
143166 .array_type,
144167 .array_type_sentinel,
145168 .enum_literal,
146 .MultilineStringLiteral,
169 .multiline_string_literal,
147170 .char_literal,
148171 .@"defer",
172 .@"errdefer",
149173 .@"catch",
150174 .error_union,
151175 .merge_error_sets,
152 .range,
176 .switch_range,
153177 .@"await",
154178 .bit_not,
155179 .negation,
156180 .negation_wrap,
157181 .@"resume",
158182 .@"try",
159 .slice_type,
160183 .slice,
161 .ArrayInitializer,
162 .ArrayInitializerDot,
163 .StructInitializer,
164 .StructInitializerDot,
184 .slice_open,
185 .slice_sentinel,
186 .array_init_one,
187 .array_init_one_comma,
188 .array_init_dot_two,
189 .array_init_dot_two_comma,
190 .array_init_dot,
191 .array_init_dot_comma,
192 .array_init,
193 .array_init_comma,
194 .struct_init_one,
195 .struct_init_one_comma,
196 .struct_init_dot_two,
197 .struct_init_dot_two_comma,
198 .struct_init_dot,
199 .struct_init_dot_comma,
200 .struct_init,
201 .struct_init_comma,
165202 .@"switch",
203 .switch_comma,
166204 .@"for",
205 .for_simple,
167206 .@"suspend",
168207 .@"continue",
169208 .@"anytype",
170 .error_type,
171 .FnProto,
209 .fn_proto_simple,
210 .fn_proto_multi,
211 .fn_proto_one,
212 .fn_proto,
213 .fn_decl,
172214 .anyframe_type,
215 .anyframe_literal,
173216 .error_set_decl,
174 .ContainerDecl,
217 .container_decl,
218 .container_decl_comma,
219 .container_decl_two,
220 .container_decl_two_comma,
221 .container_decl_arg,
222 .container_decl_arg_comma,
223 .tagged_union,
224 .tagged_union_comma,
225 .tagged_union_two,
226 .tagged_union_two_comma,
227 .tagged_union_enum_tag,
228 .tagged_union_enum_tag_comma,
175229 .@"comptime",
176230 .@"nosuspend",
231 .error_value,
177232 => return mod.failNode(scope, node, "invalid left-hand side to assignment", .{}),
178233
179234 .builtin_call,
......@@ -192,10 +247,10 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.I
192247 }
193248 },
194249
195 // can be assigned to
250 // These can be assigned to.
196251 .unwrap_optional,
197252 .deref,
198 .period,
253 .field_access,
199254 .array_access,
200255 .identifier,
201256 .grouped_expression,
......@@ -210,22 +265,33 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.I
210265/// result instruction can be used to inspect whether it is isNoReturn() but that is it,
211266/// it must otherwise not be used.
212267pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!*zir.Inst {
213 switch (node.tag) {
268 const tree = scope.tree();
269 const main_tokens = tree.nodes.items(.main_token);
270 const token_tags = tree.tokens.items(.tag);
271 const node_datas = tree.nodes.items(.data);
272 const node_tags = tree.nodes.items(.tag);
273 const token_starts = tree.tokens.items(.start);
274
275 switch (node_tags[node]) {
214276 .root => unreachable, // Top-level declaration.
215277 .@"usingnamespace" => unreachable, // Top-level declaration.
216278 .test_decl => unreachable, // Top-level declaration.
217 .doc_comment => unreachable, // Top-level declaration.
218 .var_decl => unreachable, // Handled in `blockExpr`.
279 .container_field_init => unreachable, // Top-level declaration.
280 .container_field_align => unreachable, // Top-level declaration.
281 .container_field => unreachable, // Top-level declaration.
282 .fn_decl => unreachable, // Top-level declaration.
283
284 .global_var_decl => unreachable, // Handled in `blockExpr`.
285 .local_var_decl => unreachable, // Handled in `blockExpr`.
286 .simple_var_decl => unreachable, // Handled in `blockExpr`.
287 .aligned_var_decl => unreachable, // Handled in `blockExpr`.
288
219289 .switch_case => unreachable, // Handled in `switchExpr`.
220 .switch_else => unreachable, // Handled in `switchExpr`.
221 .range => unreachable, // Handled in `switchExpr`.
222 .Else => unreachable, // Handled explicitly the control flow expression functions.
223 .Payload => unreachable, // Handled explicitly.
224 .PointerPayload => unreachable, // Handled explicitly.
225 .PointerIndexPayload => unreachable, // Handled explicitly.
226 .ErrorTag => unreachable, // Handled explicitly.
227 .FieldInitializer => unreachable, // Handled explicitly.
228 .ContainerField => unreachable, // Handled explicitly.
290 .switch_case_one => unreachable, // Handled in `switchExpr`.
291 .switch_range => unreachable, // Handled in `switchExpr`.
292
293 .asm_output => unreachable, // Handled in `asmExpr`.
294 .asm_input => unreachable, // Handled in `asmExpr`.
229295
230296 .assign => return rvalueVoid(mod, scope, rl, node, try assign(mod, scope, node)),
231297 .assign_bit_and => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .bit_and)),
......@@ -276,30 +342,28 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
276342
277343 .identifier => return identifier(mod, scope, rl, node),
278344
279 .asm_simple => return assembly(mod, scope, rl, tree.asmSimple(node)),
280 .@"asm" => return assembly(mod, scope, rl, tree.asmFull(node)),
345 .asm_simple => return asmExpr(mod, scope, rl, tree.asmSimple(node)),
346 .@"asm" => return asmExpr(mod, scope, rl, tree.asmFull(node)),
281347
282348 .string_literal => return stringLiteral(mod, scope, rl, node),
283349 .multiline_string_literal => return multilineStringLiteral(mod, scope, rl, node),
284350
285351 .integer_literal => return integerLiteral(mod, scope, rl, node),
286352
287 .builtin_call => return builtinCall(mod, scope, rl, node),
288
289353 .builtin_call_two, .builtin_call_two_comma => {
290 if (datas[node].lhs == 0) {
354 if (node_datas[node].lhs == 0) {
291355 const params = [_]ast.Node.Index{};
292356 return builtinCall(mod, scope, rl, node, &params);
293 } else if (datas[node].rhs == 0) {
294 const params = [_]ast.Node.Index{datas[node].lhs};
357 } else if (node_datas[node].rhs == 0) {
358 const params = [_]ast.Node.Index{node_datas[node].lhs};
295359 return builtinCall(mod, scope, rl, node, &params);
296360 } else {
297 const params = [_]ast.Node.Index{ datas[node].lhs, datas[node].rhs };
361 const params = [_]ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs };
298362 return builtinCall(mod, scope, rl, node, &params);
299363 }
300364 },
301365 .builtin_call, .builtin_call_comma => {
302 const params = tree.extra_data[datas[node].lhs..datas[node].rhs];
366 const params = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs];
303367 return builtinCall(mod, scope, rl, node, params);
304368 },
305369
......@@ -311,20 +375,20 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
311375 return callExpr(mod, scope, rl, tree.callFull(node));
312376 },
313377
314 .@"unreachable" => {
378 .unreachable_literal => {
315379 const main_token = main_tokens[node];
316380 const src = token_starts[main_token];
317381 return addZIRNoOp(mod, scope, src, .unreachable_safe);
318382 },
319383 .@"return" => return ret(mod, scope, node),
320 .period => return field(mod, scope, rl, node),
384 .field_access => return field(mod, scope, rl, node),
321385 .float_literal => return floatLiteral(mod, scope, rl, node),
322386
323387 .if_simple => return ifExpr(mod, scope, rl, tree.ifSimple(node)),
324 .@"if" => return ifExpr(mode, scope, rl, tree.ifFull(node)),
388 .@"if" => return ifExpr(mod, scope, rl, tree.ifFull(node)),
325389
326390 .while_simple => return whileExpr(mod, scope, rl, tree.whileSimple(node)),
327 .while_cont => return whileExpr(mod, scope, tree.whileCont(node)),
391 .while_cont => return whileExpr(mod, scope, rl, tree.whileCont(node)),
328392 .@"while" => return whileExpr(mod, scope, rl, tree.whileFull(node)),
329393
330394 .for_simple => return forExpr(mod, scope, rl, tree.forSimple(node)),
......@@ -389,7 +453,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
389453 return rvalue(mod, scope, rl, result);
390454 },
391455 .unwrap_optional => {
392 const operand = try expr(mod, scope, rl, node.lhs);
456 const operand = try expr(mod, scope, rl, node_datas[node].lhs);
393457 const op: zir.Inst.Tag = switch (rl) {
394458 .ref => .optional_payload_safe_ptr,
395459 else => .optional_payload_safe,
......@@ -449,7 +513,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
449513 },
450514 .@"catch" => {
451515 const catch_token = main_tokens[node];
452 const payload_token: ?TokenIndex = if (token_tags[catch_token + 1] == .pipe)
516 const payload_token: ?ast.TokenIndex = if (token_tags[catch_token + 1] == .pipe)
453517 catch_token + 2
454518 else
455519 null;
......@@ -506,6 +570,34 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
506570 null,
507571 ),
508572 },
573
574 .ptr_type_aligned => return ptrType(mod, scope, rl, tree.ptrTypeAligned(node)),
575 .ptr_type_sentinel => return ptrType(mod, scope, rl, tree.ptrTypeSentinel(node)),
576 .ptr_type => return ptrType(mod, scope, rl, tree.ptrType(node)),
577 .ptr_type_bit_range => return ptrType(mod, scope, rl, tree.ptrTypeBitRange(node)),
578
579 .container_decl,
580 .container_decl_comma,
581 => return containerDecl(mod, scope, rl, tree.containerDecl(node)),
582 .container_decl_two, .container_decl_two_comma => {
583 var buffer: [2]ast.Node.Index = undefined;
584 return containerDecl(mod, scope, rl, tree.containerDeclTwo(&buffer, node));
585 },
586 .container_decl_arg,
587 .container_decl_arg_comma,
588 => return containerDecl(mod, scope, rl, tree.containerDeclArg(node)),
589
590 .tagged_union,
591 .tagged_union_comma,
592 => return containerDecl(mod, scope, rl, tree.taggedUnion(node)),
593 .tagged_union_two, .tagged_union_two_comma => {
594 var buffer: [2]ast.Node.Index = undefined;
595 return containerDecl(mod, scope, rl, tree.taggedUnionTwo(&buffer, node));
596 },
597 .tagged_union_enum_tag,
598 .tagged_union_enum_tag_comma,
599 => return containerDecl(mod, scope, rl, tree.taggedUnionEnumTag(node)),
600
509601 .@"break" => return breakExpr(mod, scope, rl, node),
510602 .@"continue" => return continueExpr(mod, scope, rl, node),
511603 .grouped_expression => return expr(mod, scope, rl, node_datas[node].lhs),
......@@ -518,12 +610,41 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
518610 .@"switch", .switch_comma => return switchExpr(mod, scope, rl, node),
519611
520612 .@"defer" => return mod.failNode(scope, node, "TODO implement astgen.expr for .defer", .{}),
613 .@"errdefer" => return mod.failNode(scope, node, "TODO implement astgen.expr for .errdefer", .{}),
521614 .@"await" => return mod.failNode(scope, node, "TODO implement astgen.expr for .await", .{}),
522615 .@"resume" => return mod.failNode(scope, node, "TODO implement astgen.expr for .resume", .{}),
523616 .@"try" => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}),
617
618 .array_init_one,
619 .array_init_one_comma,
620 .array_init_dot_two,
621 .array_init_dot_two_comma,
622 .array_init_dot,
623 .array_init_dot_comma,
624 .array_init,
625 .array_init_comma,
626 => return mod.failNode(scope, node, "TODO implement astgen.expr for array literals", .{}),
627
628 .struct_init_one,
629 .struct_init_one_comma,
630 .struct_init_dot_two,
631 .struct_init_dot_two_comma,
632 .struct_init_dot,
633 .struct_init_dot_comma,
634 .struct_init,
635 .struct_init_comma,
636 => return mod.failNode(scope, node, "TODO implement astgen.expr for struct literals", .{}),
637
524638 .@"suspend" => return mod.failNode(scope, node, "TODO implement astgen.expr for .suspend", .{}),
525639 .@"anytype" => return mod.failNode(scope, node, "TODO implement astgen.expr for .anytype", .{}),
640 .fn_proto_simple,
641 .fn_proto_multi,
642 .fn_proto_one,
643 .fn_proto,
644 => return mod.failNode(scope, node, "TODO implement astgen.expr for function prototypes", .{}),
645
526646 .@"nosuspend" => return mod.failNode(scope, node, "TODO implement astgen.expr for .nosuspend", .{}),
647 .error_value => return mod.failNode(scope, node, "TODO implement astgen.expr for .error_value", .{}),
527648 }
528649}
529650
......@@ -572,6 +693,8 @@ fn breakExpr(
572693 const tree = parent_scope.tree();
573694 const node_datas = tree.nodes.items(.data);
574695 const main_tokens = tree.nodes.items(.main_token);
696 const token_starts = tree.tokens.items(.start);
697
575698 const src = token_starts[main_tokens[node]];
576699 const break_label = node_datas[node].lhs;
577700 const rhs = node_datas[node].rhs;
......@@ -646,6 +769,8 @@ fn continueExpr(
646769 const tree = parent_scope.tree();
647770 const node_datas = tree.nodes.items(.data);
648771 const main_tokens = tree.nodes.items(.main_token);
772 const token_starts = tree.tokens.items(.start);
773
649774 const src = token_starts[main_tokens[node]];
650775 const break_label = node_datas[node].lhs;
651776
......@@ -702,7 +827,7 @@ pub fn blockExpr(
702827 const main_tokens = tree.nodes.items(.main_token);
703828 const token_tags = tree.tokens.items(.tag);
704829
705 const lbrace = main_tokens[node];
830 const lbrace = main_tokens[block_node];
706831 if (token_tags[lbrace - 1] == .colon) {
707832 return labeledBlockExpr(mod, scope, rl, block_node, statements, .block);
708833 }
......@@ -721,8 +846,9 @@ fn checkLabelRedefinition(mod: *Module, parent_scope: *Scope, label: ast.TokenIn
721846 if (gen_zir.label) |prev_label| {
722847 if (try tokenIdentEql(mod, parent_scope, label, prev_label.token)) {
723848 const tree = parent_scope.tree();
724 const node_datas = tree.nodes.items(.data);
725849 const main_tokens = tree.nodes.items(.main_token);
850 const token_starts = tree.tokens.items(.start);
851
726852 const label_src = token_starts[label];
727853 const prev_label_src = token_starts[prev_label.token];
728854
......@@ -770,9 +896,9 @@ fn labeledBlockExpr(
770896 assert(zir_tag == .block or zir_tag == .block_comptime);
771897
772898 const tree = parent_scope.tree();
773 const node_datas = tree.nodes.items(.data);
774899 const main_tokens = tree.nodes.items(.main_token);
775900 const token_starts = tree.tokens.items(.start);
901 const token_tags = tree.tokens.items(.tag);
776902
777903 const lbrace = main_tokens[block_node];
778904 const label_token = lbrace - 1;
......@@ -813,10 +939,10 @@ fn labeledBlockExpr(
813939 defer block_scope.labeled_breaks.deinit(mod.gpa);
814940 defer block_scope.labeled_store_to_block_ptr_list.deinit(mod.gpa);
815941
816 try blockExprStmts(mod, &block_scope.base, block_node, block_node.statements());
942 try blockExprStmts(mod, &block_scope.base, block_node, statements);
817943
818944 if (!block_scope.label.?.used) {
819 return mod.fail(parent_scope, token_starts[block_node.label], "unused block label", .{});
945 return mod.failTok(parent_scope, label_token, "unused block label", .{});
820946 }
821947
822948 try gen_zir.instructions.append(mod.gpa, &block_inst.base);
......@@ -860,21 +986,23 @@ fn blockExprStmts(
860986 statements: []const ast.Node.Index,
861987) !void {
862988 const tree = parent_scope.tree();
863 const node_datas = tree.nodes.items(.data);
864989 const main_tokens = tree.nodes.items(.main_token);
990 const token_starts = tree.tokens.items(.start);
991 const node_tags = tree.nodes.items(.tag);
865992
866993 var block_arena = std.heap.ArenaAllocator.init(mod.gpa);
867994 defer block_arena.deinit();
868995
869996 var scope = parent_scope;
870997 for (statements) |statement| {
871 const src = token_starts[statement.firstToken()];
998 const src = token_starts[tree.firstToken(statement)];
872999 _ = try addZIRNoOp(mod, scope, src, .dbg_stmt);
873 switch (statement.tag) {
874 .var_decl => {
875 const var_decl_node = statement.castTag(.var_decl).?;
876 scope = try varDecl(mod, scope, var_decl_node, &block_arena.allocator);
877 },
1000 switch (node_tags[statement]) {
1001 .global_var_decl => scope = try varDecl(mod, scope, &block_arena.allocator, tree.globalVarDecl(statement)),
1002 .local_var_decl => scope = try varDecl(mod, scope, &block_arena.allocator, tree.localVarDecl(statement)),
1003 .simple_var_decl => scope = try varDecl(mod, scope, &block_arena.allocator, tree.simpleVarDecl(statement)),
1004 .aligned_var_decl => scope = try varDecl(mod, scope, &block_arena.allocator, tree.alignedVarDecl(statement)),
1005
8781006 .assign => try assign(mod, scope, statement),
8791007 .assign_bit_and => try assignOp(mod, scope, statement, .bit_and),
8801008 .assign_bit_or => try assignOp(mod, scope, statement, .bit_or),
......@@ -903,20 +1031,23 @@ fn blockExprStmts(
9031031fn varDecl(
9041032 mod: *Module,
9051033 scope: *Scope,
906 node: *ast.Node.var_decl,
9071034 block_arena: *Allocator,
1035 var_decl: ast.full.VarDecl,
9081036) InnerError!*Scope {
909 if (node.getComptimeToken()) |comptime_token| {
1037 if (var_decl.comptime_token) |comptime_token| {
9101038 return mod.failTok(scope, comptime_token, "TODO implement comptime locals", .{});
9111039 }
912 if (node.getAlignNode()) |align_node| {
913 return mod.failNode(scope, align_node, "TODO implement alignment on locals", .{});
1040 if (var_decl.ast.align_node != 0) {
1041 return mod.failNode(scope, var_decl.ast.align_node, "TODO implement alignment on locals", .{});
9141042 }
9151043 const tree = scope.tree();
916 const node_datas = tree.nodes.items(.data);
9171044 const main_tokens = tree.nodes.items(.main_token);
918 const name_src = token_starts[node.name_token];
919 const ident_name = try mod.identifierTokenString(scope, node.name_token);
1045 const token_starts = tree.tokens.items(.start);
1046 const token_tags = tree.tokens.items(.tag);
1047
1048 const name_token = var_decl.ast.mut_token + 1;
1049 const name_src = token_starts[name_token];
1050 const ident_name = try mod.identifierTokenString(scope, name_token);
9201051
9211052 // Local variables shadowing detection, including function parameters.
9221053 {
......@@ -962,20 +1093,21 @@ fn varDecl(
9621093 // TODO add note for other definition
9631094 return mod.fail(scope, name_src, "redefinition of '{s}'", .{ident_name});
9641095 }
965 const init_node = node.getInitNode() orelse
1096 if (var_decl.ast.init_node == 0) {
9661097 return mod.fail(scope, name_src, "variables must be initialized", .{});
1098 }
9671099
968 switch (tree.token_ids[node.mut_token]) {
1100 switch (token_tags[var_decl.ast.mut_token]) {
9691101 .keyword_const => {
9701102 // Depending on the type of AST the initialization expression is, we may need an lvalue
9711103 // or an rvalue as a result location. If it is an rvalue, we can use the instruction as
9721104 // the variable, no memory location needed.
973 if (!nodeMayNeedMemoryLocation(init_node, scope)) {
974 const result_loc: ResultLoc = if (node.getTypeNode()) |type_node|
975 .{ .ty = try typeExpr(mod, scope, type_node) }
1105 if (!nodeMayNeedMemoryLocation(scope, var_decl.ast.init_node)) {
1106 const result_loc: ResultLoc = if (var_decl.ast.type_node != 0)
1107 .{ .ty = try typeExpr(mod, scope, var_decl.ast.type_node) }
9761108 else
9771109 .none;
978 const init_inst = try expr(mod, scope, result_loc, init_node);
1110 const init_inst = try expr(mod, scope, result_loc, var_decl.ast.init_node);
9791111 const sub_scope = try block_arena.create(Scope.LocalVal);
9801112 sub_scope.* = .{
9811113 .parent = scope,
......@@ -999,8 +1131,8 @@ fn varDecl(
9991131
10001132 var resolve_inferred_alloc: ?*zir.Inst = null;
10011133 var opt_type_inst: ?*zir.Inst = null;
1002 if (node.getTypeNode()) |type_node| {
1003 const type_inst = try typeExpr(mod, &init_scope.base, type_node);
1134 if (var_decl.ast.type_node != 0) {
1135 const type_inst = try typeExpr(mod, &init_scope.base, var_decl.ast.type_node);
10041136 opt_type_inst = type_inst;
10051137 init_scope.rl_ptr = try addZIRUnOp(mod, &init_scope.base, name_src, .alloc, type_inst);
10061138 } else {
......@@ -1009,7 +1141,7 @@ fn varDecl(
10091141 init_scope.rl_ptr = &alloc.base;
10101142 }
10111143 const init_result_loc: ResultLoc = .{ .block_ptr = &init_scope };
1012 const init_inst = try expr(mod, &init_scope.base, init_result_loc, init_node);
1144 const init_inst = try expr(mod, &init_scope.base, init_result_loc, var_decl.ast.init_node);
10131145 const parent_zir = &scope.getGenZIR().instructions;
10141146 if (init_scope.rvalue_rl_count == 1) {
10151147 // Result location pointer not used. We don't need an alloc for this
......@@ -1069,8 +1201,11 @@ fn varDecl(
10691201 },
10701202 .keyword_var => {
10711203 var resolve_inferred_alloc: ?*zir.Inst = null;
1072 const var_data: struct { result_loc: ResultLoc, alloc: *zir.Inst } = if (node.getTypeNode()) |type_node| a: {
1073 const type_inst = try typeExpr(mod, scope, type_node);
1204 const var_data: struct {
1205 result_loc: ResultLoc,
1206 alloc: *zir.Inst,
1207 } = if (var_decl.ast.type_node != 0) a: {
1208 const type_inst = try typeExpr(mod, scope, var_decl.ast.type_node);
10741209 const alloc = try addZIRUnOp(mod, scope, name_src, .alloc_mut, type_inst);
10751210 break :a .{ .alloc = alloc, .result_loc = .{ .ptr = alloc } };
10761211 } else a: {
......@@ -1078,7 +1213,7 @@ fn varDecl(
10781213 resolve_inferred_alloc = &alloc.base;
10791214 break :a .{ .alloc = &alloc.base, .result_loc = .{ .inferred_ptr = alloc } };
10801215 };
1081 const init_inst = try expr(mod, scope, var_data.result_loc, init_node);
1216 const init_inst = try expr(mod, scope, var_data.result_loc, var_decl.ast.init_node);
10821217 if (resolve_inferred_alloc) |inst| {
10831218 _ = try addZIRUnOp(mod, scope, name_src, .resolve_inferred_alloc, inst);
10841219 }
......@@ -1099,13 +1234,15 @@ fn assign(mod: *Module, scope: *Scope, infix_node: ast.Node.Index) InnerError!vo
10991234 const tree = scope.tree();
11001235 const node_datas = tree.nodes.items(.data);
11011236 const main_tokens = tree.nodes.items(.main_token);
1237 const node_tags = tree.nodes.items(.tag);
1238
11021239 const lhs = node_datas[infix_node].lhs;
11031240 const rhs = node_datas[infix_node].rhs;
11041241 if (node_tags[lhs] == .identifier) {
11051242 // This intentionally does not support `@"_"` syntax.
11061243 const ident_name = tree.tokenSlice(main_tokens[lhs]);
11071244 if (mem.eql(u8, ident_name, "_")) {
1108 _ = try expr(mod, scope, .discard, infix_node.rhs);
1245 _ = try expr(mod, scope, .discard, rhs);
11091246 return;
11101247 }
11111248 }
......@@ -1122,6 +1259,7 @@ fn assignOp(
11221259 const tree = scope.tree();
11231260 const node_datas = tree.nodes.items(.data);
11241261 const main_tokens = tree.nodes.items(.main_token);
1262 const token_starts = tree.tokens.items(.start);
11251263
11261264 const lhs_ptr = try lvalExpr(mod, scope, node_datas[infix_node].lhs);
11271265 const lhs = try addZIRUnOp(mod, scope, lhs_ptr.src, .deref, lhs_ptr);
......@@ -1136,6 +1274,7 @@ fn boolNot(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.In
11361274 const tree = scope.tree();
11371275 const node_datas = tree.nodes.items(.data);
11381276 const main_tokens = tree.nodes.items(.main_token);
1277 const token_starts = tree.tokens.items(.start);
11391278
11401279 const src = token_starts[main_tokens[node]];
11411280 const bool_type = try addZIRInstConst(mod, scope, src, .{
......@@ -1150,6 +1289,7 @@ fn bitNot(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Ins
11501289 const tree = scope.tree();
11511290 const node_datas = tree.nodes.items(.data);
11521291 const main_tokens = tree.nodes.items(.main_token);
1292 const token_starts = tree.tokens.items(.start);
11531293
11541294 const src = token_starts[main_tokens[node]];
11551295 const operand = try expr(mod, scope, .none, node_datas[node].lhs);
......@@ -1165,6 +1305,7 @@ fn negation(
11651305 const tree = scope.tree();
11661306 const node_datas = tree.nodes.items(.data);
11671307 const main_tokens = tree.nodes.items(.main_token);
1308 const token_starts = tree.tokens.items(.start);
11681309
11691310 const src = token_starts[main_tokens[node]];
11701311 const lhs = try addZIRInstConst(mod, scope, src, .{
......@@ -1175,53 +1316,61 @@ fn negation(
11751316 return addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs);
11761317}
11771318
1178fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo, rhs: *ast.Node, size: std.builtin.TypeInfo.Pointer.Size) InnerError!*zir.Inst {
1319fn ptrType(
1320 mod: *Module,
1321 scope: *Scope,
1322 rl: ResultLoc,
1323 ptr_info: ast.full.PtrType,
1324) InnerError!*zir.Inst {
1325 const tree = scope.tree();
1326 const token_starts = tree.tokens.items(.start);
1327
1328 const src = token_starts[ptr_info.ast.main_token];
1329
11791330 const simple = ptr_info.allowzero_token == null and
1180 ptr_info.align_info == null and
1331 ptr_info.ast.align_node == 0 and
11811332 ptr_info.volatile_token == null and
1182 ptr_info.sentinel == null;
1333 ptr_info.ast.sentinel == 0;
11831334
11841335 if (simple) {
1185 const child_type = try typeExpr(mod, scope, rhs);
1336 const child_type = try typeExpr(mod, scope, ptr_info.ast.child_type);
11861337 const mutable = ptr_info.const_token == null;
1187 // TODO stage1 type inference bug
11881338 const T = zir.Inst.Tag;
1189 return addZIRUnOp(mod, scope, src, switch (size) {
1339 const result = try addZIRUnOp(mod, scope, src, switch (ptr_info.size) {
11901340 .One => if (mutable) T.single_mut_ptr_type else T.single_const_ptr_type,
11911341 .Many => if (mutable) T.many_mut_ptr_type else T.many_const_ptr_type,
11921342 .C => if (mutable) T.c_mut_ptr_type else T.c_const_ptr_type,
11931343 .Slice => if (mutable) T.mut_slice_type else T.const_slice_type,
11941344 }, child_type);
1345 return rvalue(mod, scope, rl, result);
11951346 }
11961347
11971348 var kw_args: std.meta.fieldInfo(zir.Inst.PtrType, .kw_args).field_type = .{};
1198 kw_args.size = size;
1349 kw_args.size = ptr_info.size;
11991350 kw_args.@"allowzero" = ptr_info.allowzero_token != null;
1200 if (ptr_info.align_info) |some| {
1201 kw_args.@"align" = try expr(mod, scope, .none, some.node);
1202 if (some.bit_range) |bit_range| {
1203 kw_args.align_bit_start = try expr(mod, scope, .none, bit_range.start);
1204 kw_args.align_bit_end = try expr(mod, scope, .none, bit_range.end);
1351 if (ptr_info.ast.align_node != 0) {
1352 kw_args.@"align" = try expr(mod, scope, .none, ptr_info.ast.align_node);
1353 if (ptr_info.ast.bit_range_start != 0) {
1354 kw_args.align_bit_start = try expr(mod, scope, .none, ptr_info.ast.bit_range_start);
1355 kw_args.align_bit_end = try expr(mod, scope, .none, ptr_info.ast.bit_range_end);
12051356 }
12061357 }
12071358 kw_args.mutable = ptr_info.const_token == null;
12081359 kw_args.@"volatile" = ptr_info.volatile_token != null;
1209 if (ptr_info.sentinel) |some| {
1210 kw_args.sentinel = try expr(mod, scope, .none, some);
1211 }
1212
1213 const child_type = try typeExpr(mod, scope, rhs);
1214 if (kw_args.sentinel) |some| {
1215 kw_args.sentinel = try addZIRBinOp(mod, scope, some.src, .as, child_type, some);
1360 const child_type = try typeExpr(mod, scope, ptr_info.ast.child_type);
1361 if (ptr_info.ast.sentinel != 0) {
1362 kw_args.sentinel = try expr(mod, scope, .{ .ty = child_type }, ptr_info.ast.sentinel);
12161363 }
1217
1218 return addZIRInst(mod, scope, src, zir.Inst.PtrType, .{ .child_type = child_type }, kw_args);
1364 const result = try addZIRInst(mod, scope, src, zir.Inst.PtrType, .{ .child_type = child_type }, kw_args);
1365 return rvalue(mod, scope, rl, result);
12191366}
12201367
12211368fn arrayType(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !*zir.Inst {
12221369 const tree = scope.tree();
12231370 const main_tokens = tree.nodes.items(.main_token);
12241371 const node_datas = tree.nodes.items(.data);
1372 const token_starts = tree.tokens.items(.start);
1373
12251374 const src = token_starts[main_tokens[node]];
12261375 const usize_type = try addZIRInstConst(mod, scope, src, .{
12271376 .ty = Type.initTag(.type),
......@@ -1246,6 +1395,9 @@ fn arrayType(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !
12461395fn arrayTypeSentinel(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !*zir.Inst {
12471396 const tree = scope.tree();
12481397 const main_tokens = tree.nodes.items(.main_token);
1398 const token_starts = tree.tokens.items(.start);
1399 const node_datas = tree.nodes.items(.data);
1400
12491401 const len_node = node_datas[node].lhs;
12501402 const extra = tree.extraData(node_datas[node].rhs, ast.Node.ArrayTypeSentinel);
12511403 const src = token_starts[main_tokens[node]];
......@@ -1274,6 +1426,8 @@ fn containerField(
12741426 node: *ast.Node.ContainerField,
12751427) InnerError!*zir.Inst {
12761428 const tree = scope.tree();
1429 const token_starts = tree.tokens.items(.start);
1430
12771431 const src = token_starts[tree.firstToken(node)];
12781432 const name = try mod.identifierTokenString(scope, node.name_token);
12791433
......@@ -1305,9 +1459,18 @@ fn containerField(
13051459 });
13061460}
13071461
1308fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.ContainerDecl) InnerError!*zir.Inst {
1462fn containerDecl(
1463 mod: *Module,
1464 scope: *Scope,
1465 rl: ResultLoc,
1466 container_decl: ast.full.ContainerDecl,
1467) InnerError!*zir.Inst {
13091468 const tree = scope.tree();
1310 const src = token_starts[node.kind_token];
1469 const token_starts = tree.tokens.items(.start);
1470 const node_tags = tree.nodes.items(.tag);
1471 const token_tags = tree.tokens.items(.tag);
1472
1473 const src = token_starts[container_decl.ast.main_token];
13111474
13121475 var gen_scope: Scope.GenZIR = .{
13131476 .parent = scope,
......@@ -1321,9 +1484,12 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
13211484 var fields = std.ArrayList(*zir.Inst).init(mod.gpa);
13221485 defer fields.deinit();
13231486
1324 for (node.fieldsAndDecls()) |fd| {
1325 if (fd.castTag(.ContainerField)) |f| {
1326 try fields.append(try containerField(mod, &gen_scope.base, f));
1487 for (container_decl.ast.members) |member| {
1488 switch (node_tags[member]) {
1489 .container_field_init, .container_field_align, .container_field => {
1490 try fields.append(try containerField(mod, &gen_scope.base, member));
1491 },
1492 else => continue,
13271493 }
13281494 }
13291495
......@@ -1332,19 +1498,22 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
13321498 const arena = &decl_arena.allocator;
13331499
13341500 var layout: std.builtin.TypeInfo.ContainerLayout = .Auto;
1335 if (node.layout_token) |some| switch (tree.token_ids[some]) {
1501 if (container_decl.layout_token) |some| switch (token_tags[some]) {
13361502 .keyword_extern => layout = .Extern,
13371503 .keyword_packed => layout = .Packed,
13381504 else => unreachable,
13391505 };
13401506
1341 const container_type = switch (tree.token_ids[node.kind_token]) {
1507 // TODO this implementation is incorrect. The types must be created in semantic
1508 // analysis, not astgen, because the same ZIR is re-used for multiple inline function calls,
1509 // comptime function calls, and generic function instantiations, and these
1510 // must result in different instances of container types.
1511 const container_type = switch (token_tags[container_decl.ast.main_token]) {
13421512 .keyword_enum => blk: {
1343 const tag_type: ?*zir.Inst = switch (node.init_arg_expr) {
1344 .Type => |t| try typeExpr(mod, &gen_scope.base, t),
1345 .None => null,
1346 .Enum => unreachable,
1347 };
1513 const tag_type: ?*zir.Inst = if (container_decl.ast.arg != 0)
1514 try typeExpr(mod, &gen_scope.base, container_decl.ast.arg)
1515 else
1516 null;
13481517 const inst = try addZIRInst(mod, &gen_scope.base, src, zir.Inst.EnumType, .{
13491518 .fields = try arena.dupe(*zir.Inst, fields.items),
13501519 }, .{
......@@ -1367,7 +1536,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
13671536 break :blk Type.initPayload(&enum_type.base);
13681537 },
13691538 .keyword_struct => blk: {
1370 assert(node.init_arg_expr == .None);
1539 assert(container_decl.ast.arg == 0);
13711540 const inst = try addZIRInst(mod, &gen_scope.base, src, zir.Inst.StructType, .{
13721541 .fields = try arena.dupe(*zir.Inst, fields.items),
13731542 }, .{
......@@ -1389,21 +1558,16 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
13891558 break :blk Type.initPayload(&struct_type.base);
13901559 },
13911560 .keyword_union => blk: {
1392 const init_inst = switch (node.init_arg_expr) {
1393 .Enum => |e| if (e) |t| try typeExpr(mod, &gen_scope.base, t) else null,
1394 .None => null,
1395 .Type => |t| try typeExpr(mod, &gen_scope.base, t),
1396 };
1397 const init_kind: zir.Inst.UnionType.InitKind = switch (node.init_arg_expr) {
1398 .Enum => .enum_type,
1399 .None => .none,
1400 .Type => .tag_type,
1401 };
1561 const init_inst: ?*zir.Inst = if (container_decl.ast.arg != 0)
1562 try typeExpr(mod, &gen_scope.base, container_decl.ast.arg)
1563 else
1564 null;
1565 const has_enum_token = container_decl.ast.enum_token != null;
14021566 const inst = try addZIRInst(mod, &gen_scope.base, src, zir.Inst.UnionType, .{
14031567 .fields = try arena.dupe(*zir.Inst, fields.items),
14041568 }, .{
14051569 .layout = layout,
1406 .init_kind = init_kind,
1570 .has_enum_token = has_enum_token,
14071571 .init_inst = init_inst,
14081572 });
14091573 const union_type = try arena.create(Type.Payload.Union);
......@@ -1437,7 +1601,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
14371601 else => unreachable,
14381602 };
14391603 const val = try Value.Tag.ty.create(arena, container_type);
1440 const decl = try mod.createContainerDecl(scope, node.kind_token, &decl_arena, .{
1604 const decl = try mod.createContainerDecl(scope, container_decl.ast.main_token, &decl_arena, .{
14411605 .ty = Type.initTag(.type),
14421606 .val = val,
14431607 });
......@@ -1459,6 +1623,7 @@ fn errorSetDecl(
14591623 const tree = scope.tree();
14601624 const main_tokens = tree.nodes.items(.main_token);
14611625 const token_tags = tree.tokens.items(.tag);
1626 const token_starts = tree.tokens.items(.start);
14621627
14631628 // Count how many fields there are.
14641629 const error_token = main_tokens[node];
......@@ -1500,15 +1665,17 @@ fn orelseCatchExpr(
15001665 mod: *Module,
15011666 scope: *Scope,
15021667 rl: ResultLoc,
1503 lhs: *ast.Node,
1668 lhs: ast.Node.Index,
15041669 op_token: ast.TokenIndex,
15051670 cond_op: zir.Inst.Tag,
15061671 unwrap_op: zir.Inst.Tag,
15071672 unwrap_code_op: zir.Inst.Tag,
1508 rhs: *ast.Node,
1509 payload_node: ?*ast.Node,
1673 rhs: ast.Node.Index,
1674 payload_token: ?ast.TokenIndex,
15101675) InnerError!*zir.Inst {
15111676 const tree = scope.tree();
1677 const token_starts = tree.tokens.items(.start);
1678
15121679 const src = token_starts[op_token];
15131680
15141681 var block_scope: Scope.GenZIR = .{
......@@ -1547,12 +1714,11 @@ fn orelseCatchExpr(
15471714
15481715 var err_val_scope: Scope.LocalVal = undefined;
15491716 const then_sub_scope = blk: {
1550 const payload = payload_node orelse break :blk &then_scope.base;
1551
1552 const err_name = tree.tokenSlice(payload.castTag(.Payload).?.error_symbol.firstToken());
1553 if (mem.eql(u8, err_name, "_"))
1554 break :blk &then_scope.base;
1555
1717 const payload = payload_token orelse break :blk &then_scope.base;
1718 if (mem.eql(u8, tree.tokenSlice(payload), "_")) {
1719 return mod.failTok(&then_scope.base, payload, "discard of error capture; omit it instead", .{});
1720 }
1721 const err_name = try mod.identifierTokenString(scope, payload);
15561722 err_val_scope = .{
15571723 .parent = &then_scope.base,
15581724 .gen_zir = &then_scope,
......@@ -1685,18 +1851,20 @@ pub fn field(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) I
16851851 const tree = scope.tree();
16861852 const token_starts = tree.tokens.items(.start);
16871853 const main_tokens = tree.nodes.items(.main_token);
1854 const node_datas = tree.nodes.items(.data);
1855
16881856 const dot_token = main_tokens[node];
16891857 const src = token_starts[dot_token];
16901858 const field_ident = dot_token + 1;
16911859 const field_name = try mod.identifierTokenString(scope, field_ident);
16921860 if (rl == .ref) {
16931861 return addZirInstTag(mod, scope, src, .field_ptr, .{
1694 .object = try expr(mod, scope, .ref, node.lhs),
1862 .object = try expr(mod, scope, .ref, node_datas[node].lhs),
16951863 .field_name = field_name,
16961864 });
16971865 } else {
16981866 return rvalue(mod, scope, rl, try addZirInstTag(mod, scope, src, .field_val, .{
1699 .object = try expr(mod, scope, .none, node.lhs),
1867 .object = try expr(mod, scope, .none, node_datas[node].lhs),
17001868 .field_name = field_name,
17011869 }));
17021870 }
......@@ -1711,6 +1879,8 @@ fn arrayAccess(
17111879 const tree = scope.tree();
17121880 const main_tokens = tree.nodes.items(.main_token);
17131881 const token_starts = tree.tokens.items(.start);
1882 const node_datas = tree.nodes.items(.data);
1883
17141884 const src = token_starts[main_tokens[node]];
17151885 const usize_type = try addZIRInstConst(mod, scope, src, .{
17161886 .ty = Type.initTag(.type),
......@@ -1737,6 +1907,7 @@ fn sliceExpr(
17371907) InnerError!*zir.Inst {
17381908 const tree = scope.tree();
17391909 const token_starts = tree.tokens.items(.start);
1910
17401911 const src = token_starts[slice.ast.lbracket];
17411912
17421913 const usize_type = try addZIRInstConst(mod, scope, src, .{
......@@ -1786,6 +1957,7 @@ fn simpleBinOp(
17861957 const tree = scope.tree();
17871958 const node_datas = tree.nodes.items(.data);
17881959 const main_tokens = tree.nodes.items(.main_token);
1960 const token_starts = tree.tokens.items(.start);
17891961
17901962 const lhs = try expr(mod, scope, .none, node_datas[infix_node].lhs);
17911963 const rhs = try expr(mod, scope, .none, node_datas[infix_node].rhs);
......@@ -1804,6 +1976,7 @@ fn boolBinOp(
18041976 const tree = scope.tree();
18051977 const node_datas = tree.nodes.items(.data);
18061978 const main_tokens = tree.nodes.items(.main_token);
1979 const token_starts = tree.tokens.items(.start);
18071980
18081981 const src = token_starts[main_tokens[infix_node]];
18091982 const bool_type = try addZIRInstConst(mod, scope, src, .{
......@@ -1899,13 +2072,14 @@ fn ifExpr(
18992072 defer block_scope.instructions.deinit(mod.gpa);
19002073
19012074 const tree = scope.tree();
1902 const node_datas = tree.nodes.items(.data);
19032075 const main_tokens = tree.nodes.items(.main_token);
2076 const token_starts = tree.tokens.items(.start);
2077
19042078 const if_src = token_starts[if_full.ast.if_token];
19052079
19062080 const cond = c: {
19072081 // TODO https://github.com/ziglang/zig/issues/7929
1908 if (if_full.ast.error_token) |error_token| {
2082 if (if_full.error_token) |error_token| {
19092083 return mod.failTok(scope, error_token, "TODO implement if error union", .{});
19102084 } else if (if_full.payload_token) |payload_token| {
19112085 return mod.failTok(scope, payload_token, "TODO implement if optional", .{});
......@@ -1966,7 +2140,7 @@ fn ifExpr(
19662140 };
19672141 } else
19682142 .{
1969 .src = token_starts[tree.lastToken(if_full.then_expr)],
2143 .src = token_starts[tree.lastToken(if_full.ast.then_expr)],
19702144 .result = null,
19712145 };
19722146
......@@ -2042,8 +2216,9 @@ fn whileExpr(
20422216 defer continue_scope.instructions.deinit(mod.gpa);
20432217
20442218 const tree = scope.tree();
2045 const node_datas = tree.nodes.items(.data);
20462219 const main_tokens = tree.nodes.items(.main_token);
2220 const token_starts = tree.tokens.items(.start);
2221
20472222 const while_src = token_starts[while_full.ast.while_token];
20482223 const void_type = try addZIRInstConst(mod, scope, while_src, .{
20492224 .ty = Type.initTag(.type),
......@@ -2051,16 +2226,16 @@ fn whileExpr(
20512226 });
20522227 const cond = c: {
20532228 // TODO https://github.com/ziglang/zig/issues/7929
2054 if (while_full.ast.error_token) |error_token| {
2229 if (while_full.error_token) |error_token| {
20552230 return mod.failTok(scope, error_token, "TODO implement while error union", .{});
20562231 } else if (while_full.payload_token) |payload_token| {
20572232 return mod.failTok(scope, payload_token, "TODO implement while optional", .{});
20582233 } else {
2059 const bool_type = try addZIRInstConst(mod, &block_scope.base, while_src, .{
2234 const bool_type = try addZIRInstConst(mod, &continue_scope.base, while_src, .{
20602235 .ty = Type.initTag(.type),
20612236 .val = Value.initTag(.bool_type),
20622237 });
2063 break :c try expr(mod, &block_scope.base, .{ .ty = bool_type }, while_full.ast.cond_expr);
2238 break :c try expr(mod, &continue_scope.base, .{ .ty = bool_type }, while_full.ast.cond_expr);
20642239 }
20652240 };
20662241
......@@ -2128,7 +2303,7 @@ fn whileExpr(
21282303 };
21292304 defer else_scope.instructions.deinit(mod.gpa);
21302305
2131 const else_node = if_full.ast.else_expr;
2306 const else_node = while_full.ast.else_expr;
21322307 const else_info: struct { src: usize, result: ?*zir.Inst } = if (else_node != 0) blk: {
21332308 loop_scope.break_count += 1;
21342309 const sub_scope = &else_scope.base;
......@@ -2138,7 +2313,7 @@ fn whileExpr(
21382313 };
21392314 } else
21402315 .{
2141 .src = token_starts[tree.lastToken(then_node)],
2316 .src = token_starts[tree.lastToken(while_full.ast.then_expr)],
21422317 .result = null,
21432318 };
21442319
......@@ -2181,8 +2356,10 @@ fn forExpr(
21812356
21822357 // Set up variables and constants.
21832358 const tree = scope.tree();
2184 const node_datas = tree.nodes.items(.data);
21852359 const main_tokens = tree.nodes.items(.main_token);
2360 const token_starts = tree.tokens.items(.start);
2361 const token_tags = tree.tokens.items(.tag);
2362
21862363 const for_src = token_starts[for_full.ast.while_token];
21872364 const index_ptr = blk: {
21882365 const usize_type = try addZIRInstConst(mod, scope, for_src, .{
......@@ -2299,7 +2476,7 @@ fn forExpr(
22992476 else
23002477 break :blk &then_scope.base;
23012478 if (mem.eql(u8, tree.tokenSlice(index_token), "_")) {
2302 return mod.failTok(&then_scope.base, index_token, "discard of index capture not allowed; omit it instead", .{});
2479 return mod.failTok(&then_scope.base, index_token, "discard of index capture; omit it instead", .{});
23032480 }
23042481 const index_name = try mod.identifierTokenString(&then_scope.base, index_token);
23052482 index_scope = .{
......@@ -2334,7 +2511,7 @@ fn forExpr(
23342511 };
23352512 } else
23362513 .{
2337 .src = token_starts[tree.lastToken(then_node)],
2514 .src = token_starts[tree.lastToken(for_full.ast.then_expr)],
23382515 .result = null,
23392516 };
23402517
......@@ -2386,10 +2563,12 @@ fn switchExpr(
23862563 const node_datas = tree.nodes.items(.data);
23872564 const main_tokens = tree.nodes.items(.main_token);
23882565 const token_tags = tree.tokens.items(.tag);
2566 const token_starts = tree.tokens.items(.start);
2567 const node_tags = tree.nodes.items(.tag);
23892568
23902569 const switch_token = main_tokens[switch_node];
2391 const target_node = datas[switch_node].lhs;
2392 const extra = tree.extraData(datas[switch_node].rhs, ast.switch_node.SubRange);
2570 const target_node = node_datas[switch_node].lhs;
2571 const extra = tree.extraData(node_datas[switch_node].rhs, ast.Node.SubRange);
23932572 const case_nodes = tree.extra_data[extra.start..extra.end];
23942573
23952574 const switch_src = token_starts[switch_token];
......@@ -2552,7 +2731,7 @@ fn switchExpr(
25522731 defer else_scope.instructions.deinit(mod.gpa);
25532732
25542733 // Now generate all but the special cases.
2555 var special_case: ?ast.Node.Index = null;
2734 var special_case: ?ast.full.SwitchCase = null;
25562735 var items_index: usize = 0;
25572736 var case_index: usize = 0;
25582737 for (case_nodes) |case_node| {
......@@ -2582,7 +2761,7 @@ fn switchExpr(
25822761 {
25832762 const item = items.items[items_index];
25842763 items_index += 1;
2585 try switchCaseExpr(mod, &case_scope.base, block_scope.break_result_loc, block, case, target, target_ptr);
2764 try switchCaseExpr(mod, &case_scope.base, block_scope.break_result_loc, block, case, target);
25862765
25872766 cases[case_index] = .{
25882767 .item = item,
......@@ -2638,7 +2817,7 @@ fn switchExpr(
26382817
26392818 // reset cond_scope for then_body
26402819 case_scope.instructions.items.len = 0;
2641 try switchCaseExpr(mod, &case_scope.base, block_scope.break_result_loc, block, case, target, target_ptr);
2820 try switchCaseExpr(mod, &case_scope.base, block_scope.break_result_loc, block, case, target);
26422821 condbr.positionals.then_body = .{
26432822 .instructions = try scope.arena().dupe(*zir.Inst, case_scope.instructions.items),
26442823 };
......@@ -2655,7 +2834,7 @@ fn switchExpr(
26552834
26562835 // Finally generate else block or a break.
26572836 if (special_case) |case| {
2658 try switchCaseExpr(mod, &else_scope.base, block_scope.break_result_loc, block, case, target, target_ptr);
2837 try switchCaseExpr(mod, &else_scope.base, block_scope.break_result_loc, block, case, target);
26592838 } else {
26602839 // Not handling all possible cases is a compile error.
26612840 _ = try addZIRNoOp(mod, &else_scope.base, switch_src, .unreachable_unsafe);
......@@ -2674,11 +2853,13 @@ fn switchCaseExpr(
26742853 block: *zir.Inst.Block,
26752854 case: ast.full.SwitchCase,
26762855 target: *zir.Inst,
2677 target_ptr: ?*zir.Inst,
26782856) !void {
26792857 const tree = scope.tree();
26802858 const node_datas = tree.nodes.items(.data);
26812859 const main_tokens = tree.nodes.items(.main_token);
2860 const token_starts = tree.tokens.items(.start);
2861 const token_tags = tree.tokens.items(.tag);
2862
26822863 const case_src = token_starts[case.ast.arrow_token];
26832864 const sub_scope = blk: {
26842865 const payload_token = case.payload_token orelse break :blk scope;
......@@ -2690,11 +2871,11 @@ fn switchCaseExpr(
26902871 const value_name = tree.tokenSlice(ident);
26912872 if (mem.eql(u8, value_name, "_")) {
26922873 if (is_ptr) {
2693 return mod.failTok(scope, payload.ptr_token.?, "pointer modifier invalid on discard", .{});
2874 return mod.failTok(scope, payload_token, "pointer modifier invalid on discard", .{});
26942875 }
26952876 break :blk scope;
26962877 }
2697 return mod.failNode(scope, payload.value_symbol, "TODO implement switch value payload", .{});
2878 return mod.failTok(scope, ident, "TODO implement switch value payload", .{});
26982879 };
26992880
27002881 const case_body = try expr(mod, sub_scope, rl, case.ast.target_expr);
......@@ -2710,10 +2891,12 @@ fn ret(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst {
27102891 const tree = scope.tree();
27112892 const node_datas = tree.nodes.items(.data);
27122893 const main_tokens = tree.nodes.items(.main_token);
2894 const token_starts = tree.tokens.items(.start);
2895
27132896 const src = token_starts[main_tokens[node]];
27142897 const rhs_node = node_datas[node].lhs;
27152898 if (rhs_node != 0) {
2716 if (nodeMayNeedMemoryLocation(rhs_node, scope)) {
2899 if (nodeMayNeedMemoryLocation(scope, rhs_node)) {
27172900 const ret_ptr = try addZIRNoOp(mod, scope, src, .ret_ptr);
27182901 const operand = try expr(mod, scope, .{ .ptr = ret_ptr }, rhs_node);
27192902 return addZIRUnOp(mod, scope, src, .@"return", operand);
......@@ -2737,8 +2920,8 @@ fn identifier(
27372920 defer tracy.end();
27382921
27392922 const tree = scope.tree();
2740 const node_datas = tree.nodes.items(.data);
27412923 const main_tokens = tree.nodes.items(.main_token);
2924 const token_starts = tree.tokens.items(.start);
27422925
27432926 const ident_token = main_tokens[ident];
27442927 const ident_name = try mod.identifierTokenString(scope, ident_token);
......@@ -2826,6 +3009,27 @@ fn identifier(
28263009 return mod.failNode(scope, ident, "use of undeclared identifier '{s}'", .{ident_name});
28273010}
28283011
3012fn parseStringLiteral(mod: *Module, scope: *Scope, token: ast.TokenIndex) ![]u8 {
3013 const tree = scope.tree();
3014 const token_tags = tree.tokens.items(.tag);
3015 const token_starts = tree.tokens.items(.start);
3016 assert(token_tags[token] == .string_literal);
3017 const unparsed = tree.tokenSlice(token);
3018 const arena = scope.arena();
3019 var bad_index: usize = undefined;
3020 const bytes = std.zig.parseStringLiteral(arena, unparsed, &bad_index) catch |err| switch (err) {
3021 error.InvalidCharacter => {
3022 const bad_byte = unparsed[bad_index];
3023 const src = token_starts[token];
3024 return mod.fail(scope, src + bad_index, "invalid string literal character: '{c}'", .{
3025 bad_byte,
3026 });
3027 },
3028 else => |e| return e,
3029 };
3030 return bytes;
3031}
3032
28293033fn stringLiteral(
28303034 mod: *Module,
28313035 scope: *Scope,
......@@ -2833,23 +3037,11 @@ fn stringLiteral(
28333037 str_lit: ast.Node.Index,
28343038) InnerError!*zir.Inst {
28353039 const tree = scope.tree();
2836 const node_datas = tree.nodes.items(.data);
28373040 const main_tokens = tree.nodes.items(.main_token);
3041 const token_starts = tree.tokens.items(.start);
28383042
28393043 const str_lit_token = main_tokens[str_lit];
2840 const unparsed_bytes = tree.tokenSlice(str_lit_token);
2841 const arena = scope.arena();
2842
2843 var bad_index: usize = undefined;
2844 const bytes = std.zig.parseStringLiteral(arena, unparsed_bytes, &bad_index) catch |err| switch (err) {
2845 error.InvalidCharacter => {
2846 const bad_byte = unparsed_bytes[bad_index];
2847 const src = token_starts[str_lit_token];
2848 return mod.fail(scope, src + bad_index, "invalid string literal character: '{c}'\n", .{bad_byte});
2849 },
2850 else => |e| return e,
2851 };
2852
3044 const bytes = try parseStringLiteral(mod, scope, str_lit_token);
28533045 const src = token_starts[str_lit_token];
28543046 const str_inst = try addZIRInst(mod, scope, src, zir.Inst.Str, .{ .bytes = bytes }, .{});
28553047 return rvalue(mod, scope, rl, str_inst);
......@@ -2864,9 +3056,10 @@ fn multilineStringLiteral(
28643056 const tree = scope.tree();
28653057 const node_datas = tree.nodes.items(.data);
28663058 const main_tokens = tree.nodes.items(.main_token);
3059 const token_starts = tree.tokens.items(.start);
28673060
2868 const start = node_datas[node].lhs;
2869 const end = node_datas[node].rhs;
3061 const start = node_datas[str_lit].lhs;
3062 const end = node_datas[str_lit].rhs;
28703063
28713064 // Count the number of bytes to allocate.
28723065 const len: usize = len: {
......@@ -2905,9 +3098,10 @@ fn multilineStringLiteral(
29053098
29063099fn charLiteral(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !*zir.Inst {
29073100 const tree = scope.tree();
2908 const node_datas = tree.nodes.items(.data);
29093101 const main_tokens = tree.nodes.items(.main_token);
29103102 const main_token = main_tokens[node];
3103 const token_starts = tree.tokens.items(.start);
3104
29113105 const src = token_starts[main_token];
29123106 const slice = tree.tokenSlice(main_token);
29133107
......@@ -2934,6 +3128,7 @@ fn integerLiteral(
29343128 const arena = scope.arena();
29353129 const tree = scope.tree();
29363130 const main_tokens = tree.nodes.items(.main_token);
3131 const token_starts = tree.tokens.items(.start);
29373132
29383133 const int_token = main_tokens[int_lit];
29393134 const prefixed_bytes = tree.tokenSlice(int_token);
......@@ -2972,6 +3167,8 @@ fn floatLiteral(
29723167 const arena = scope.arena();
29733168 const tree = scope.tree();
29743169 const main_tokens = tree.nodes.items(.main_token);
3170 const token_starts = tree.tokens.items(.start);
3171
29753172 const main_token = main_tokens[float_lit];
29763173 const bytes = tree.tokenSlice(main_token);
29773174 if (bytes.len > 2 and bytes[1] == 'x') {
......@@ -2988,17 +3185,18 @@ fn floatLiteral(
29883185 return rvalue(mod, scope, rl, result);
29893186}
29903187
2991fn assembly(mod: *Module, scope: *Scope, rl: ResultLoc, full: ast.full.Asm) InnerError!*zir.Inst {
3188fn asmExpr(mod: *Module, scope: *Scope, rl: ResultLoc, full: ast.full.Asm) InnerError!*zir.Inst {
29923189 const arena = scope.arena();
29933190 const tree = scope.tree();
2994 const node_datas = tree.nodes.items(.data);
29953191 const main_tokens = tree.nodes.items(.main_token);
3192 const token_starts = tree.tokens.items(.start);
3193 const node_datas = tree.nodes.items(.data);
29963194
29973195 if (full.outputs.len != 0) {
29983196 return mod.failTok(scope, full.ast.asm_token, "TODO implement asm with an output", .{});
29993197 }
30003198
3001 const inputs = try arena.alloc(*zir.Inst, full.inputs.len);
3199 const inputs = try arena.alloc([]const u8, full.inputs.len);
30023200 const args = try arena.alloc(*zir.Inst, full.inputs.len);
30033201
30043202 const src = token_starts[full.ast.asm_token];
......@@ -3010,15 +3208,16 @@ fn assembly(mod: *Module, scope: *Scope, rl: ResultLoc, full: ast.full.Asm) Inne
30103208
30113209 for (full.inputs) |input, i| {
30123210 // TODO semantically analyze constraints
3013 inputs[i] = try expr(mod, scope, str_type_rl, input.constraint);
3014 args[i] = try expr(mod, scope, .none, input.expr);
3211 const constraint_token = main_tokens[input] + 2;
3212 inputs[i] = try parseStringLiteral(mod, scope, constraint_token);
3213 args[i] = try expr(mod, scope, .none, node_datas[input].lhs);
30153214 }
30163215
30173216 const return_type = try addZIRInstConst(mod, scope, src, .{
30183217 .ty = Type.initTag(.type),
30193218 .val = Value.initTag(.void_type),
30203219 });
3021 const asm_inst = try addZIRInst(mod, scope, src, zir.Inst.@"asm", .{
3220 const asm_inst = try addZIRInst(mod, scope, src, zir.Inst.Asm, .{
30223221 .asm_source = try expr(mod, scope, str_type_rl, full.ast.template),
30233222 .return_type = return_type,
30243223 }, .{
......@@ -3185,8 +3384,9 @@ fn builtinCall(
31853384 params: []const ast.Node.Index,
31863385) InnerError!*zir.Inst {
31873386 const tree = scope.tree();
3188 const node_datas = tree.nodes.items(.data);
31893387 const main_tokens = tree.nodes.items(.main_token);
3388 const token_starts = tree.tokens.items(.start);
3389
31903390 const builtin_token = main_tokens[call];
31913391 const builtin_name = tree.tokenSlice(builtin_token);
31923392
......@@ -3200,11 +3400,13 @@ fn builtinCall(
32003400 builtin_name,
32013401 });
32023402 };
3203 if (info.param_count != params.len) {
3204 const s = if (params.len == 1) "" else "s";
3205 return mod.failTok(scope, builtin_token, "expected {d} parameter{s}, found {d}", .{
3206 expected, s, found,
3207 });
3403 if (info.param_count) |expected| {
3404 if (expected != params.len) {
3405 const s = if (expected == 1) "" else "s";
3406 return mod.failTok(scope, builtin_token, "expected {d} parameter{s}, found {d}", .{
3407 expected, s, params.len,
3408 });
3409 }
32083410 }
32093411 const src = token_starts[builtin_token];
32103412
......@@ -3237,7 +3439,7 @@ fn builtinCall(
32373439 },
32383440 .compile_error => {
32393441 const target = try expr(mod, scope, .none, params[0]);
3240 const result = addZIRUnOp(mod, scope, src, .compile_error, target);
3442 const result = try addZIRUnOp(mod, scope, src, .compile_error, target);
32413443 return rvalue(mod, scope, rl, result);
32423444 },
32433445 .set_eval_branch_quota => {
......@@ -3386,8 +3588,9 @@ fn callExpr(
33863588 }
33873589
33883590 const tree = scope.tree();
3389 const node_datas = tree.nodes.items(.data);
33903591 const main_tokens = tree.nodes.items(.main_token);
3592 const token_starts = tree.tokens.items(.start);
3593
33913594 const lhs = try expr(mod, scope, .none, call.ast.fn_expr);
33923595
33933596 const args = try scope.getGenZIR().arena.alloc(*zir.Inst, call.ast.params.len);
......@@ -3446,23 +3649,26 @@ fn getSimplePrimitiveValue(name: []const u8) ?TypedValue {
34463649 return null;
34473650}
34483651
3449fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
3652fn nodeMayNeedMemoryLocation(scope: *Scope, start_node: ast.Node.Index) bool {
3653 const tree = scope.tree();
3654 const node_tags = tree.nodes.items(.tag);
3655 const node_datas = tree.nodes.items(.data);
3656 const main_tokens = tree.nodes.items(.main_token);
3657 const token_tags = tree.tokens.items(.tag);
3658
34503659 var node = start_node;
34513660 while (true) {
3452 switch (node.tag) {
3453 .Root,
3661 switch (node_tags[node]) {
3662 .root,
34543663 .@"usingnamespace",
34553664 .test_decl,
3456 .doc_comment,
34573665 .switch_case,
3458 .switch_else,
3459 .Else,
3460 .Payload,
3461 .PointerPayload,
3462 .PointerIndexPayload,
3463 .ContainerField,
3464 .ErrorTag,
3465 .FieldInitializer,
3666 .switch_case_one,
3667 .container_field_init,
3668 .container_field_align,
3669 .container_field,
3670 .asm_output,
3671 .asm_input,
34663672 => unreachable,
34673673
34683674 .@"return",
......@@ -3470,8 +3676,12 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
34703676 .@"continue",
34713677 .bit_not,
34723678 .bool_not,
3473 .var_decl,
3679 .global_var_decl,
3680 .local_var_decl,
3681 .simple_var_decl,
3682 .aligned_var_decl,
34743683 .@"defer",
3684 .@"errdefer",
34753685 .address_of,
34763686 .optional_type,
34773687 .negation,
......@@ -3479,27 +3689,46 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
34793689 .@"resume",
34803690 .array_type,
34813691 .array_type_sentinel,
3482 .PtrType,
3483 .slice_type,
3692 .ptr_type_aligned,
3693 .ptr_type_sentinel,
3694 .ptr_type,
3695 .ptr_type_bit_range,
34843696 .@"suspend",
34853697 .@"anytype",
3486 .error_type,
3487 .FnProto,
3698 .fn_proto_simple,
3699 .fn_proto_multi,
3700 .fn_proto_one,
3701 .fn_proto,
3702 .fn_decl,
34883703 .anyframe_type,
3704 .anyframe_literal,
34893705 .integer_literal,
34903706 .float_literal,
34913707 .enum_literal,
34923708 .string_literal,
3493 .MultilineStringLiteral,
3709 .multiline_string_literal,
34943710 .char_literal,
3495 .bool_literal,
3711 .true_literal,
3712 .false_literal,
34963713 .null_literal,
34973714 .undefined_literal,
3498 .@"unreachable",
3715 .unreachable_literal,
34993716 .identifier,
35003717 .error_set_decl,
3501 .ContainerDecl,
3718 .container_decl,
3719 .container_decl_comma,
3720 .container_decl_two,
3721 .container_decl_two_comma,
3722 .container_decl_arg,
3723 .container_decl_arg_comma,
3724 .tagged_union,
3725 .tagged_union_comma,
3726 .tagged_union_two,
3727 .tagged_union_two_comma,
3728 .tagged_union_enum_tag,
3729 .tagged_union_enum_tag_comma,
35023730 .@"asm",
3731 .asm_simple,
35033732 .add,
35043733 .add_wrap,
35053734 .array_cat,
......@@ -3537,14 +3766,16 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
35373766 .mod,
35383767 .mul,
35393768 .mul_wrap,
3540 .range,
3541 .period,
3769 .switch_range,
3770 .field_access,
35423771 .sub,
35433772 .sub_wrap,
35443773 .slice,
3774 .slice_open,
3775 .slice_sentinel,
35453776 .deref,
35463777 .array_access,
3547 .block,
3778 .error_value,
35483779 .while_simple, // This variant cannot have an else expression.
35493780 .while_cont, // This variant cannot have an else expression.
35503781 .for_simple, // This variant cannot have an else expression.
......@@ -3558,18 +3789,30 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
35583789 .@"comptime",
35593790 .@"nosuspend",
35603791 .unwrap_optional,
3561 => node = datas[node].lhs,
3792 => node = node_datas[node].lhs,
35623793
35633794 // Forward the question to the RHS sub-expression.
35643795 .@"catch",
35653796 .@"orelse",
3566 => node = datas[node].rhs,
3797 => node = node_datas[node].rhs,
35673798
35683799 // True because these are exactly the expressions we need memory locations for.
3569 .ArrayInitializer,
3570 .ArrayInitializerDot,
3571 .StructInitializer,
3572 .StructInitializerDot,
3800 .array_init_one,
3801 .array_init_one_comma,
3802 .array_init_dot_two,
3803 .array_init_dot_two_comma,
3804 .array_init_dot,
3805 .array_init_dot_comma,
3806 .array_init,
3807 .array_init_comma,
3808 .struct_init_one,
3809 .struct_init_one_comma,
3810 .struct_init_dot_two,
3811 .struct_init_dot_two_comma,
3812 .struct_init_dot,
3813 .struct_init_dot_comma,
3814 .struct_init,
3815 .struct_init_comma,
35733816 => return true,
35743817
35753818 // True because depending on comptime conditions, sub-expressions
......@@ -3578,6 +3821,7 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
35783821 .@"if", // This variant always has an else expression.
35793822 .@"for", // This variant always has an else expression.
35803823 .@"switch",
3824 .switch_comma,
35813825 .call_one,
35823826 .call_one_comma,
35833827 .async_call_one,
......@@ -3588,10 +3832,10 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
35883832 .async_call_comma,
35893833 => return true,
35903834
3591 block_two,
3592 block_two_semicolon,
3593 block,
3594 block_semicolon,
3835 .block_two,
3836 .block_two_semicolon,
3837 .block,
3838 .block_semicolon,
35953839 => {
35963840 const lbrace = main_tokens[node];
35973841 if (token_tags[lbrace - 1] == .colon) {
......@@ -3603,7 +3847,11 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
36033847 }
36043848 },
36053849
3606 .builtin_call => {
3850 .builtin_call,
3851 .builtin_call_comma,
3852 .builtin_call_two,
3853 .builtin_call_two_comma,
3854 => {
36073855 const builtin_token = main_tokens[node];
36083856 const builtin_name = tree.tokenSlice(builtin_token);
36093857 // If the builtin is an invalid name, we don't cause an error here; instead
......@@ -3661,7 +3909,6 @@ fn rvalueVoid(
36613909 result: void,
36623910) InnerError!*zir.Inst {
36633911 const tree = scope.tree();
3664 const node_datas = tree.nodes.items(.data);
36653912 const main_tokens = tree.nodes.items(.main_token);
36663913 const src = tree.tokens.items(.start)[tree.firstToken(node)];
36673914 const void_inst = try addZIRInstConst(mod, scope, src, .{
......@@ -3765,7 +4012,7 @@ pub fn addZirInstT(
37654012 src: usize,
37664013 comptime T: type,
37674014 tag: zir.Inst.Tag,
3768 positionals: std.meta.fieldInfo(tag.Type(), .positionals).field_type,
4015 positionals: std.meta.fieldInfo(T, .positionals).field_type,
37694016) !*T {
37704017 const gen_zir = scope.getGenZIR();
37714018 try gen_zir.instructions.ensureCapacity(mod.gpa, gen_zir.instructions.items.len + 1);
src/zir.zig+5-11
......@@ -863,8 +863,8 @@ pub const Inst = struct {
863863 kw_args: struct {
864864 @"volatile": bool = false,
865865 output: ?*Inst = null,
866 inputs: []*Inst = &[0]*Inst{},
867 clobbers: []*Inst = &[0]*Inst{},
866 inputs: []const []const u8 = &.{},
867 clobbers: []const []const u8 = &.{},
868868 args: []*Inst = &[0]*Inst{},
869869 },
870870 };
......@@ -1192,16 +1192,9 @@ pub const Inst = struct {
11921192 },
11931193 kw_args: struct {
11941194 init_inst: ?*Inst = null,
1195 init_kind: InitKind = .none,
1195 has_enum_token: bool,
11961196 layout: std.builtin.TypeInfo.ContainerLayout = .Auto,
11971197 },
1198
1199 // TODO error: values of type '(enum literal)' must be comptime known
1200 pub const InitKind = enum {
1201 enum_type,
1202 tag_type,
1203 none,
1204 };
12051198 };
12061199
12071200 pub const SwitchBr = struct {
......@@ -1413,6 +1406,7 @@ const Writer = struct {
14131406 }
14141407 switch (@TypeOf(param)) {
14151408 *Inst => return self.writeInstParamToStream(stream, param),
1409 ?*Inst => return self.writeInstParamToStream(stream, param.?),
14161410 []*Inst => {
14171411 try stream.writeByte('[');
14181412 for (param) |inst, i| {
......@@ -1480,7 +1474,7 @@ const Writer = struct {
14801474 const name = self.loop_table.get(param).?;
14811475 return stream.print("\"{}\"", .{std.zig.fmtEscapes(name)});
14821476 },
1483 [][]const u8 => {
1477 [][]const u8, []const []const u8 => {
14841478 try stream.writeByte('[');
14851479 for (param) |str, i| {
14861480 if (i != 0) {
src/zir_sema.zig+7-5
......@@ -2023,19 +2023,21 @@ fn zirDeref(mod: *Module, scope: *Scope, deref: *zir.Inst.UnOp) InnerError!*Inst
20232023fn zirAsm(mod: *Module, scope: *Scope, assembly: *zir.Inst.Asm) InnerError!*Inst {
20242024 const tracy = trace(@src());
20252025 defer tracy.end();
2026
20262027 const return_type = try resolveType(mod, scope, assembly.positionals.return_type);
20272028 const asm_source = try resolveConstString(mod, scope, assembly.positionals.asm_source);
20282029 const output = if (assembly.kw_args.output) |o| try resolveConstString(mod, scope, o) else null;
20292030
2030 const inputs = try scope.arena().alloc([]const u8, assembly.kw_args.inputs.len);
2031 const clobbers = try scope.arena().alloc([]const u8, assembly.kw_args.clobbers.len);
2032 const args = try scope.arena().alloc(*Inst, assembly.kw_args.args.len);
2031 const arena = scope.arena();
2032 const inputs = try arena.alloc([]const u8, assembly.kw_args.inputs.len);
2033 const clobbers = try arena.alloc([]const u8, assembly.kw_args.clobbers.len);
2034 const args = try arena.alloc(*Inst, assembly.kw_args.args.len);
20332035
20342036 for (inputs) |*elem, i| {
2035 elem.* = try resolveConstString(mod, scope, assembly.kw_args.inputs[i]);
2037 elem.* = try arena.dupe(u8, assembly.kw_args.inputs[i]);
20362038 }
20372039 for (clobbers) |*elem, i| {
2038 elem.* = try resolveConstString(mod, scope, assembly.kw_args.clobbers[i]);
2040 elem.* = try arena.dupe(u8, assembly.kw_args.clobbers[i]);
20392041 }
20402042 for (args) |*elem, i| {
20412043 const arg = try resolveInst(mod, scope, assembly.kw_args.args[i]);