authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-02-17 15:51:48-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-01 16:35:26-07:00
logbb1dffcf32b5f59c2eaadbb522063d6c0415d924
tree05764a0ce0a1d852eb9046085f68e3ae7d4e8410
parentf3be721785013de85faf5d0fa454a7a8bc049c0b

much of the compiler upgraded to new API


26 files changed, 816 insertions(+), 846 deletions(-)

lib/std/crypto/tls/Client.zig+2-2
...@@ -125,9 +125,9 @@ pub const Options = struct {...@@ -125,9 +125,9 @@ pub const Options = struct {
125 /// Verify that the server certificate is authorized by a given ca bundle.125 /// Verify that the server certificate is authorized by a given ca bundle.
126 bundle: Certificate.Bundle,126 bundle: Certificate.Bundle,
127 },127 },
128 /// If non-null, ssl secrets are logged to this file. Creating such a log file allows128 /// If non-null, ssl secrets are logged to this stream. Creating such a log file allows
129 /// other programs with access to that file to decrypt all traffic over this connection.129 /// other programs with access to that file to decrypt all traffic over this connection.
130 ssl_key_log_file: ?std.fs.File = null,130 ssl_key_log_file: ?*std.io.BufferedWriter = null,
131};131};
132132
133pub fn InitError(comptime Stream: type) type {133pub fn InitError(comptime Stream: type) type {
lib/std/io.zig-2
...@@ -282,8 +282,6 @@ pub const Reader = GenericReader;...@@ -282,8 +282,6 @@ pub const Reader = GenericReader;
282pub const Writer = @import("io/Writer.zig");282pub const Writer = @import("io/Writer.zig");
283283
284pub const AnyReader = @import("io/Reader.zig");284pub const AnyReader = @import("io/Reader.zig");
285/// Deprecated; to be removed after 0.14.0 is tagged.
286pub const AnyWriter = Writer;
287285
288pub const SeekableStream = @import("io/seekable_stream.zig").SeekableStream;286pub const SeekableStream = @import("io/seekable_stream.zig").SeekableStream;
289287
lib/std/io/BufferedWriter.zig+8-3
...@@ -663,9 +663,14 @@ pub fn printValue(...@@ -663,9 +663,14 @@ pub fn printValue(
663 }663 }
664 },664 },
665 .error_set => {665 .error_set => {
666 if (actual_fmt.len != 0) invalidFmtError(fmt, value);666 if (actual_fmt.len > 0 and actual_fmt.len[0] == 's') {
667 try bw.writeAll("error.");667 return bw.writeAll(@errorName(value));
668 return bw.writeAll(@errorName(value));668 } else if (actual_fmt.len != 0) {
669 invalidFmtError(fmt, value);
670 } else {
671 try bw.writeAll("error.");
672 return bw.writeAll(@errorName(value));
673 }
669 },674 },
670 .@"enum" => |enumInfo| {675 .@"enum" => |enumInfo| {
671 try bw.writeAll(@typeName(T));676 try bw.writeAll(@typeName(T));
lib/std/tar.zig+4-3
...@@ -603,9 +603,10 @@ fn PaxIterator(comptime ReaderType: type) type {...@@ -603,9 +603,10 @@ fn PaxIterator(comptime ReaderType: type) type {
603 return null;603 return null;
604 }604 }
605605
606 fn readUntil(self: *Self, delimiter: u8) ![]const u8 {606 fn readUntil(self: *Self, delimiter: u8) anyerror![]const u8 {
607 var fbs: std.io.FixedBufferStream = .{ .buffer = &self.scratch };607 var fbs: std.io.BufferedWriter = undefined;
608 try self.reader.streamUntilDelimiter(fbs.writer(), delimiter, null);608 fbs.initFixed(&self.scratch);
609 try self.reader.streamUntilDelimiter(&fbs, delimiter, null);
609 return fbs.getWritten();610 return fbs.getWritten();
610 }611 }
611612
lib/std/zig/Ast.zig+77-80
...@@ -199,27 +199,24 @@ pub fn parse(gpa: Allocator, source: [:0]const u8, mode: Mode) Allocator.Error!A...@@ -199,27 +199,24 @@ pub fn parse(gpa: Allocator, source: [:0]const u8, mode: Mode) Allocator.Error!A
199199
200/// `gpa` is used for allocating the resulting formatted source code.200/// `gpa` is used for allocating the resulting formatted source code.
201/// Caller owns the returned slice of bytes, allocated with `gpa`.201/// Caller owns the returned slice of bytes, allocated with `gpa`.
202pub fn render(tree: Ast, gpa: Allocator) RenderError![]u8 {202pub fn renderAlloc(tree: Ast, gpa: Allocator) RenderError![]u8 {
203 var buffer = std.ArrayList(u8).init(gpa);203 var aw: std.io.AllocatingWriter = undefined;
204 defer buffer.deinit();204 const bw = aw.init(gpa);
205 errdefer aw.deinit();
206 render(tree, gpa, bw, .{}) catch |err| return @errorCast(err); // TODO try @errorCast(...)
207 return aw.toOwnedSlice();
208}
205209
206 try tree.renderToArrayList(&buffer, .{});210pub fn render(tree: Ast, gpa: Allocator, bw: *std.io.BufferedWriter, fixups: Fixups) anyerror!void {
207 return buffer.toOwnedSlice();211 return @import("./render.zig").renderTree(gpa, bw, tree, fixups);
208}212}
209213
210pub const Fixups = private_render.Fixups;214pub const Fixups = private_render.Fixups;
211215
212pub fn renderToArrayList(tree: Ast, buffer: *std.ArrayList(u8), fixups: Fixups) RenderError!void {
213 return @import("./render.zig").renderTree(buffer, tree, fixups);
214}
215
216/// Returns an extra offset for column and byte offset of errors that216/// Returns an extra offset for column and byte offset of errors that
217/// should point after the token in the error message.217/// should point after the token in the error message.
218pub fn errorOffset(tree: Ast, parse_error: Error) u32 {218pub fn errorOffset(tree: Ast, parse_error: Error) u32 {
219 return if (parse_error.token_is_prev)219 return if (parse_error.token_is_prev) @intCast(tree.tokenSlice(parse_error.token).len) else 0;
220 @as(u32, @intCast(tree.tokenSlice(parse_error.token).len))
221 else
222 0;
223}220}
224221
225pub fn tokenLocation(self: Ast, start_offset: ByteOffset, token_index: TokenIndex) Location {222pub fn tokenLocation(self: Ast, start_offset: ByteOffset, token_index: TokenIndex) Location {
...@@ -318,254 +315,254 @@ pub fn rootDecls(tree: Ast) []const Node.Index {...@@ -318,254 +315,254 @@ pub fn rootDecls(tree: Ast) []const Node.Index {
318 }315 }
319}316}
320317
321pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {318pub fn renderError(tree: Ast, parse_error: Error, bw: *std.io.BufferedWriter) anyerror!void {
322 switch (parse_error.tag) {319 switch (parse_error.tag) {
323 .asterisk_after_ptr_deref => {320 .asterisk_after_ptr_deref => {
324 // Note that the token will point at the `.*` but ideally the source321 // Note that the token will point at the `.*` but ideally the source
325 // location would point to the `*` after the `.*`.322 // location would point to the `*` after the `.*`.
326 return stream.writeAll("'.*' cannot be followed by '*'; are you missing a space?");323 return bw.writeAll("'.*' cannot be followed by '*'; are you missing a space?");
327 },324 },
328 .chained_comparison_operators => {325 .chained_comparison_operators => {
329 return stream.writeAll("comparison operators cannot be chained");326 return bw.writeAll("comparison operators cannot be chained");
330 },327 },
331 .decl_between_fields => {328 .decl_between_fields => {
332 return stream.writeAll("declarations are not allowed between container fields");329 return bw.writeAll("declarations are not allowed between container fields");
333 },330 },
334 .expected_block => {331 .expected_block => {
335 return stream.print("expected block, found '{s}'", .{332 return bw.print("expected block, found '{s}'", .{
336 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),333 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
337 });334 });
338 },335 },
339 .expected_block_or_assignment => {336 .expected_block_or_assignment => {
340 return stream.print("expected block or assignment, found '{s}'", .{337 return bw.print("expected block or assignment, found '{s}'", .{
341 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),338 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
342 });339 });
343 },340 },
344 .expected_block_or_expr => {341 .expected_block_or_expr => {
345 return stream.print("expected block or expression, found '{s}'", .{342 return bw.print("expected block or expression, found '{s}'", .{
346 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),343 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
347 });344 });
348 },345 },
349 .expected_block_or_field => {346 .expected_block_or_field => {
350 return stream.print("expected block or field, found '{s}'", .{347 return bw.print("expected block or field, found '{s}'", .{
351 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),348 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
352 });349 });
353 },350 },
354 .expected_container_members => {351 .expected_container_members => {
355 return stream.print("expected test, comptime, var decl, or container field, found '{s}'", .{352 return bw.print("expected test, comptime, var decl, or container field, found '{s}'", .{
356 tree.tokenTag(parse_error.token).symbol(),353 tree.tokenTag(parse_error.token).symbol(),
357 });354 });
358 },355 },
359 .expected_expr => {356 .expected_expr => {
360 return stream.print("expected expression, found '{s}'", .{357 return bw.print("expected expression, found '{s}'", .{
361 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),358 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
362 });359 });
363 },360 },
364 .expected_expr_or_assignment => {361 .expected_expr_or_assignment => {
365 return stream.print("expected expression or assignment, found '{s}'", .{362 return bw.print("expected expression or assignment, found '{s}'", .{
366 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),363 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
367 });364 });
368 },365 },
369 .expected_expr_or_var_decl => {366 .expected_expr_or_var_decl => {
370 return stream.print("expected expression or var decl, found '{s}'", .{367 return bw.print("expected expression or var decl, found '{s}'", .{
371 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),368 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
372 });369 });
373 },370 },
374 .expected_fn => {371 .expected_fn => {
375 return stream.print("expected function, found '{s}'", .{372 return bw.print("expected function, found '{s}'", .{
376 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),373 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
377 });374 });
378 },375 },
379 .expected_inlinable => {376 .expected_inlinable => {
380 return stream.print("expected 'while' or 'for', found '{s}'", .{377 return bw.print("expected 'while' or 'for', found '{s}'", .{
381 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),378 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
382 });379 });
383 },380 },
384 .expected_labelable => {381 .expected_labelable => {
385 return stream.print("expected 'while', 'for', 'inline', or '{{', found '{s}'", .{382 return bw.print("expected 'while', 'for', 'inline', or '{{', found '{s}'", .{
386 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),383 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
387 });384 });
388 },385 },
389 .expected_param_list => {386 .expected_param_list => {
390 return stream.print("expected parameter list, found '{s}'", .{387 return bw.print("expected parameter list, found '{s}'", .{
391 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),388 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
392 });389 });
393 },390 },
394 .expected_prefix_expr => {391 .expected_prefix_expr => {
395 return stream.print("expected prefix expression, found '{s}'", .{392 return bw.print("expected prefix expression, found '{s}'", .{
396 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),393 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
397 });394 });
398 },395 },
399 .expected_primary_type_expr => {396 .expected_primary_type_expr => {
400 return stream.print("expected primary type expression, found '{s}'", .{397 return bw.print("expected primary type expression, found '{s}'", .{
401 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),398 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
402 });399 });
403 },400 },
404 .expected_pub_item => {401 .expected_pub_item => {
405 return stream.writeAll("expected function or variable declaration after pub");402 return bw.writeAll("expected function or variable declaration after pub");
406 },403 },
407 .expected_return_type => {404 .expected_return_type => {
408 return stream.print("expected return type expression, found '{s}'", .{405 return bw.print("expected return type expression, found '{s}'", .{
409 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),406 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
410 });407 });
411 },408 },
412 .expected_semi_or_else => {409 .expected_semi_or_else => {
413 return stream.writeAll("expected ';' or 'else' after statement");410 return bw.writeAll("expected ';' or 'else' after statement");
414 },411 },
415 .expected_semi_or_lbrace => {412 .expected_semi_or_lbrace => {
416 return stream.writeAll("expected ';' or block after function prototype");413 return bw.writeAll("expected ';' or block after function prototype");
417 },414 },
418 .expected_statement => {415 .expected_statement => {
419 return stream.print("expected statement, found '{s}'", .{416 return bw.print("expected statement, found '{s}'", .{
420 tree.tokenTag(parse_error.token).symbol(),417 tree.tokenTag(parse_error.token).symbol(),
421 });418 });
422 },419 },
423 .expected_suffix_op => {420 .expected_suffix_op => {
424 return stream.print("expected pointer dereference, optional unwrap, or field access, found '{s}'", .{421 return bw.print("expected pointer dereference, optional unwrap, or field access, found '{s}'", .{
425 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),422 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
426 });423 });
427 },424 },
428 .expected_type_expr => {425 .expected_type_expr => {
429 return stream.print("expected type expression, found '{s}'", .{426 return bw.print("expected type expression, found '{s}'", .{
430 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),427 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
431 });428 });
432 },429 },
433 .expected_var_decl => {430 .expected_var_decl => {
434 return stream.print("expected variable declaration, found '{s}'", .{431 return bw.print("expected variable declaration, found '{s}'", .{
435 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),432 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
436 });433 });
437 },434 },
438 .expected_var_decl_or_fn => {435 .expected_var_decl_or_fn => {
439 return stream.print("expected variable declaration or function, found '{s}'", .{436 return bw.print("expected variable declaration or function, found '{s}'", .{
440 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),437 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
441 });438 });
442 },439 },
443 .expected_loop_payload => {440 .expected_loop_payload => {
444 return stream.print("expected loop payload, found '{s}'", .{441 return bw.print("expected loop payload, found '{s}'", .{
445 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),442 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
446 });443 });
447 },444 },
448 .expected_container => {445 .expected_container => {
449 return stream.print("expected a struct, enum or union, found '{s}'", .{446 return bw.print("expected a struct, enum or union, found '{s}'", .{
450 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),447 tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
451 });448 });
452 },449 },
453 .extern_fn_body => {450 .extern_fn_body => {
454 return stream.writeAll("extern functions have no body");451 return bw.writeAll("extern functions have no body");
455 },452 },
456 .extra_addrspace_qualifier => {453 .extra_addrspace_qualifier => {
457 return stream.writeAll("extra addrspace qualifier");454 return bw.writeAll("extra addrspace qualifier");
458 },455 },
459 .extra_align_qualifier => {456 .extra_align_qualifier => {
460 return stream.writeAll("extra align qualifier");457 return bw.writeAll("extra align qualifier");
461 },458 },
462 .extra_allowzero_qualifier => {459 .extra_allowzero_qualifier => {
463 return stream.writeAll("extra allowzero qualifier");460 return bw.writeAll("extra allowzero qualifier");
464 },461 },
465 .extra_const_qualifier => {462 .extra_const_qualifier => {
466 return stream.writeAll("extra const qualifier");463 return bw.writeAll("extra const qualifier");
467 },464 },
468 .extra_volatile_qualifier => {465 .extra_volatile_qualifier => {
469 return stream.writeAll("extra volatile qualifier");466 return bw.writeAll("extra volatile qualifier");
470 },467 },
471 .ptr_mod_on_array_child_type => {468 .ptr_mod_on_array_child_type => {
472 return stream.print("pointer modifier '{s}' not allowed on array child type", .{469 return bw.print("pointer modifier '{s}' not allowed on array child type", .{
473 tree.tokenTag(parse_error.token).symbol(),470 tree.tokenTag(parse_error.token).symbol(),
474 });471 });
475 },472 },
476 .invalid_bit_range => {473 .invalid_bit_range => {
477 return stream.writeAll("bit range not allowed on slices and arrays");474 return bw.writeAll("bit range not allowed on slices and arrays");
478 },475 },
479 .same_line_doc_comment => {476 .same_line_doc_comment => {
480 return stream.writeAll("same line documentation comment");477 return bw.writeAll("same line documentation comment");
481 },478 },
482 .unattached_doc_comment => {479 .unattached_doc_comment => {
483 return stream.writeAll("unattached documentation comment");480 return bw.writeAll("unattached documentation comment");
484 },481 },
485 .test_doc_comment => {482 .test_doc_comment => {
486 return stream.writeAll("documentation comments cannot be attached to tests");483 return bw.writeAll("documentation comments cannot be attached to tests");
487 },484 },
488 .comptime_doc_comment => {485 .comptime_doc_comment => {
489 return stream.writeAll("documentation comments cannot be attached to comptime blocks");486 return bw.writeAll("documentation comments cannot be attached to comptime blocks");
490 },487 },
491 .varargs_nonfinal => {488 .varargs_nonfinal => {
492 return stream.writeAll("function prototype has parameter after varargs");489 return bw.writeAll("function prototype has parameter after varargs");
493 },490 },
494 .expected_continue_expr => {491 .expected_continue_expr => {
495 return stream.writeAll("expected ':' before while continue expression");492 return bw.writeAll("expected ':' before while continue expression");
496 },493 },
497494
498 .expected_semi_after_decl => {495 .expected_semi_after_decl => {
499 return stream.writeAll("expected ';' after declaration");496 return bw.writeAll("expected ';' after declaration");
500 },497 },
501 .expected_semi_after_stmt => {498 .expected_semi_after_stmt => {
502 return stream.writeAll("expected ';' after statement");499 return bw.writeAll("expected ';' after statement");
503 },500 },
504 .expected_comma_after_field => {501 .expected_comma_after_field => {
505 return stream.writeAll("expected ',' after field");502 return bw.writeAll("expected ',' after field");
506 },503 },
507 .expected_comma_after_arg => {504 .expected_comma_after_arg => {
508 return stream.writeAll("expected ',' after argument");505 return bw.writeAll("expected ',' after argument");
509 },506 },
510 .expected_comma_after_param => {507 .expected_comma_after_param => {
511 return stream.writeAll("expected ',' after parameter");508 return bw.writeAll("expected ',' after parameter");
512 },509 },
513 .expected_comma_after_initializer => {510 .expected_comma_after_initializer => {
514 return stream.writeAll("expected ',' after initializer");511 return bw.writeAll("expected ',' after initializer");
515 },512 },
516 .expected_comma_after_switch_prong => {513 .expected_comma_after_switch_prong => {
517 return stream.writeAll("expected ',' after switch prong");514 return bw.writeAll("expected ',' after switch prong");
518 },515 },
519 .expected_comma_after_for_operand => {516 .expected_comma_after_for_operand => {
520 return stream.writeAll("expected ',' after for operand");517 return bw.writeAll("expected ',' after for operand");
521 },518 },
522 .expected_comma_after_capture => {519 .expected_comma_after_capture => {
523 return stream.writeAll("expected ',' after for capture");520 return bw.writeAll("expected ',' after for capture");
524 },521 },
525 .expected_initializer => {522 .expected_initializer => {
526 return stream.writeAll("expected field initializer");523 return bw.writeAll("expected field initializer");
527 },524 },
528 .mismatched_binary_op_whitespace => {525 .mismatched_binary_op_whitespace => {
529 return stream.print("binary operator '{s}' has whitespace on one side, but not the other", .{tree.tokenTag(parse_error.token).lexeme().?});526 return bw.print("binary operator '{s}' has whitespace on one side, but not the other", .{tree.tokenTag(parse_error.token).lexeme().?});
530 },527 },
531 .invalid_ampersand_ampersand => {528 .invalid_ampersand_ampersand => {
532 return stream.writeAll("ambiguous use of '&&'; use 'and' for logical AND, or change whitespace to ' & &' for bitwise AND");529 return bw.writeAll("ambiguous use of '&&'; use 'and' for logical AND, or change whitespace to ' & &' for bitwise AND");
533 },530 },
534 .c_style_container => {531 .c_style_container => {
535 return stream.print("'{s} {s}' is invalid", .{532 return bw.print("'{s} {s}' is invalid", .{
536 parse_error.extra.expected_tag.symbol(), tree.tokenSlice(parse_error.token),533 parse_error.extra.expected_tag.symbol(), tree.tokenSlice(parse_error.token),
537 });534 });
538 },535 },
539 .zig_style_container => {536 .zig_style_container => {
540 return stream.print("to declare a container do 'const {s} = {s}'", .{537 return bw.print("to declare a container do 'const {s} = {s}'", .{
541 tree.tokenSlice(parse_error.token), parse_error.extra.expected_tag.symbol(),538 tree.tokenSlice(parse_error.token), parse_error.extra.expected_tag.symbol(),
542 });539 });
543 },540 },
544 .previous_field => {541 .previous_field => {
545 return stream.writeAll("field before declarations here");542 return bw.writeAll("field before declarations here");
546 },543 },
547 .next_field => {544 .next_field => {
548 return stream.writeAll("field after declarations here");545 return bw.writeAll("field after declarations here");
549 },546 },
550 .expected_var_const => {547 .expected_var_const => {
551 return stream.writeAll("expected 'var' or 'const' before variable declaration");548 return bw.writeAll("expected 'var' or 'const' before variable declaration");
552 },549 },
553 .wrong_equal_var_decl => {550 .wrong_equal_var_decl => {
554 return stream.writeAll("variable initialized with '==' instead of '='");551 return bw.writeAll("variable initialized with '==' instead of '='");
555 },552 },
556 .var_const_decl => {553 .var_const_decl => {
557 return stream.writeAll("use 'var' or 'const' to declare variable");554 return bw.writeAll("use 'var' or 'const' to declare variable");
558 },555 },
559 .extra_for_capture => {556 .extra_for_capture => {
560 return stream.writeAll("extra capture in for loop");557 return bw.writeAll("extra capture in for loop");
561 },558 },
562 .for_input_not_captured => {559 .for_input_not_captured => {
563 return stream.writeAll("for input is not captured");560 return bw.writeAll("for input is not captured");
564 },561 },
565562
566 .invalid_byte => {563 .invalid_byte => {
567 const tok_slice = tree.source[tree.tokens.items(.start)[parse_error.token]..];564 const tok_slice = tree.source[tree.tokens.items(.start)[parse_error.token]..];
568 return stream.print("{s} contains invalid byte: '{'}'", .{565 return bw.print("{s} contains invalid byte: '{'}'", .{
569 switch (tok_slice[0]) {566 switch (tok_slice[0]) {
570 '\'' => "character literal",567 '\'' => "character literal",
571 '"', '\\' => "string literal",568 '"', '\\' => "string literal",
...@@ -580,10 +577,10 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {...@@ -580,10 +577,10 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {
580 const found_tag = tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev));577 const found_tag = tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev));
581 const expected_symbol = parse_error.extra.expected_tag.symbol();578 const expected_symbol = parse_error.extra.expected_tag.symbol();
582 switch (found_tag) {579 switch (found_tag) {
583 .invalid => return stream.print("expected '{s}', found invalid bytes", .{580 .invalid => return bw.print("expected '{s}', found invalid bytes", .{
584 expected_symbol,581 expected_symbol,
585 }),582 }),
586 else => return stream.print("expected '{s}', found '{s}'", .{583 else => return bw.print("expected '{s}', found '{s}'", .{
587 expected_symbol, found_tag.symbol(),584 expected_symbol, found_tag.symbol(),
588 }),585 }),
589 }586 }
lib/std/zig/AstGen.zig+26-21
...@@ -11441,10 +11441,13 @@ fn parseStrLit(...@@ -11441,10 +11441,13 @@ fn parseStrLit(
11441 offset: u32,11441 offset: u32,
11442) InnerError!void {11442) InnerError!void {
11443 const raw_string = bytes[offset..];11443 const raw_string = bytes[offset..];
11444 var buf_managed = buf.toManaged(astgen.gpa);11444 const result = r: {
11445 const result = std.zig.string_literal.parseWrite(buf_managed.writer(), raw_string);11445 var aw: std.io.AllocatingWriter = undefined;
11446 buf.* = buf_managed.moveToUnmanaged();11446 const bw = aw.fromArrayList(astgen.gpa, buf);
11447 switch (try result) {11447 defer buf.* = aw.toArrayList();
11448 break :r std.zig.string_literal.parseWrite(bw, raw_string) catch |err| return @errorCast(err);
11449 };
11450 switch (result) {
11448 .success => return,11451 .success => return,
11449 .failure => |err| return astgen.failWithStrLitError(err, token, bytes, offset),11452 .failure => |err| return astgen.failWithStrLitError(err, token, bytes, offset),
11450 }11453 }
...@@ -11493,17 +11496,18 @@ fn appendErrorNodeNotes(...@@ -11493,17 +11496,18 @@ fn appendErrorNodeNotes(
11493 notes: []const u32,11496 notes: []const u32,
11494) Allocator.Error!void {11497) Allocator.Error!void {
11495 @branchHint(.cold);11498 @branchHint(.cold);
11499 const gpa = astgen.gpa;
11496 const string_bytes = &astgen.string_bytes;11500 const string_bytes = &astgen.string_bytes;
11497 const msg: Zir.NullTerminatedString = @enumFromInt(string_bytes.items.len);11501 const msg: Zir.NullTerminatedString = @enumFromInt(string_bytes.items.len);
11498 try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args);11502 try string_bytes.print(gpa, format ++ "\x00", args);
11499 const notes_index: u32 = if (notes.len != 0) blk: {11503 const notes_index: u32 = if (notes.len != 0) blk: {
11500 const notes_start = astgen.extra.items.len;11504 const notes_start = astgen.extra.items.len;
11501 try astgen.extra.ensureTotalCapacity(astgen.gpa, notes_start + 1 + notes.len);11505 try astgen.extra.ensureTotalCapacity(gpa, notes_start + 1 + notes.len);
11502 astgen.extra.appendAssumeCapacity(@intCast(notes.len));11506 astgen.extra.appendAssumeCapacity(@intCast(notes.len));
11503 astgen.extra.appendSliceAssumeCapacity(notes);11507 astgen.extra.appendSliceAssumeCapacity(notes);
11504 break :blk @intCast(notes_start);11508 break :blk @intCast(notes_start);
11505 } else 0;11509 } else 0;
11506 try astgen.compile_errors.append(astgen.gpa, .{11510 try astgen.compile_errors.append(gpa, .{
11507 .msg = msg,11511 .msg = msg,
11508 .node = node.toOptional(),11512 .node = node.toOptional(),
11509 .token = .none,11513 .token = .none,
...@@ -11587,7 +11591,7 @@ fn appendErrorTokNotesOff(...@@ -11587,7 +11591,7 @@ fn appendErrorTokNotesOff(
11587 const gpa = astgen.gpa;11591 const gpa = astgen.gpa;
11588 const string_bytes = &astgen.string_bytes;11592 const string_bytes = &astgen.string_bytes;
11589 const msg: Zir.NullTerminatedString = @enumFromInt(string_bytes.items.len);11593 const msg: Zir.NullTerminatedString = @enumFromInt(string_bytes.items.len);
11590 try string_bytes.writer(gpa).print(format ++ "\x00", args);11594 try string_bytes.print(gpa, format ++ "\x00", args);
11591 const notes_index: u32 = if (notes.len != 0) blk: {11595 const notes_index: u32 = if (notes.len != 0) blk: {
11592 const notes_start = astgen.extra.items.len;11596 const notes_start = astgen.extra.items.len;
11593 try astgen.extra.ensureTotalCapacity(gpa, notes_start + 1 + notes.len);11597 try astgen.extra.ensureTotalCapacity(gpa, notes_start + 1 + notes.len);
...@@ -11623,7 +11627,7 @@ fn errNoteTokOff(...@@ -11623,7 +11627,7 @@ fn errNoteTokOff(
11623 @branchHint(.cold);11627 @branchHint(.cold);
11624 const string_bytes = &astgen.string_bytes;11628 const string_bytes = &astgen.string_bytes;
11625 const msg: Zir.NullTerminatedString = @enumFromInt(string_bytes.items.len);11629 const msg: Zir.NullTerminatedString = @enumFromInt(string_bytes.items.len);
11626 try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args);11630 try string_bytes.print(astgen.gpa, format ++ "\x00", args);
11627 return astgen.addExtra(Zir.Inst.CompileErrors.Item{11631 return astgen.addExtra(Zir.Inst.CompileErrors.Item{
11628 .msg = msg,11632 .msg = msg,
11629 .node = .none,11633 .node = .none,
...@@ -11642,7 +11646,7 @@ fn errNoteNode(...@@ -11642,7 +11646,7 @@ fn errNoteNode(
11642 @branchHint(.cold);11646 @branchHint(.cold);
11643 const string_bytes = &astgen.string_bytes;11647 const string_bytes = &astgen.string_bytes;
11644 const msg: Zir.NullTerminatedString = @enumFromInt(string_bytes.items.len);11648 const msg: Zir.NullTerminatedString = @enumFromInt(string_bytes.items.len);
11645 try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args);11649 try string_bytes.print(astgen.gpa, format ++ "\x00", args);
11646 return astgen.addExtra(Zir.Inst.CompileErrors.Item{11650 return astgen.addExtra(Zir.Inst.CompileErrors.Item{
11647 .msg = msg,11651 .msg = msg,
11648 .node = node.toOptional(),11652 .node = node.toOptional(),
...@@ -13888,13 +13892,14 @@ fn emitDbgStmtForceCurrentIndex(gz: *GenZir, lc: LineColumn) !void {...@@ -13888,13 +13892,14 @@ fn emitDbgStmtForceCurrentIndex(gz: *GenZir, lc: LineColumn) !void {
13888 } });13892 } });
13889}13893}
1389013894
13891fn lowerAstErrors(astgen: *AstGen) !void {13895fn lowerAstErrors(astgen: *AstGen) error{OutOfMemory}!void {
13892 const gpa = astgen.gpa;13896 const gpa = astgen.gpa;
13893 const tree = astgen.tree;13897 const tree = astgen.tree;
13894 assert(tree.errors.len > 0);13898 assert(tree.errors.len > 0);
1389513899
13896 var msg: std.ArrayListUnmanaged(u8) = .empty;13900 var msg: std.io.AllocatingWriter = undefined;
13897 defer msg.deinit(gpa);13901 const msg_writer = msg.init(gpa);
13902 defer msg.deinit();
1389813903
13899 var notes: std.ArrayListUnmanaged(u32) = .empty;13904 var notes: std.ArrayListUnmanaged(u32) = .empty;
13900 defer notes.deinit(gpa);13905 defer notes.deinit(gpa);
...@@ -13928,20 +13933,20 @@ fn lowerAstErrors(astgen: *AstGen) !void {...@@ -13928,20 +13933,20 @@ fn lowerAstErrors(astgen: *AstGen) !void {
13928 .extra = .{ .offset = bad_off },13933 .extra = .{ .offset = bad_off },
13929 };13934 };
13930 msg.clearRetainingCapacity();13935 msg.clearRetainingCapacity();
13931 try tree.renderError(err, msg.writer(gpa));13936 tree.renderError(err, msg_writer) catch |e| return @errorCast(e); // TODO try @errorCast(...)
13932 return try astgen.appendErrorTokNotesOff(tok, bad_off, "{s}", .{msg.items}, notes.items);13937 return try astgen.appendErrorTokNotesOff(tok, bad_off, "{s}", .{msg.getWritten()}, notes.items);
13933 }13938 }
1393413939
13935 var cur_err = tree.errors[0];13940 var cur_err = tree.errors[0];
13936 for (tree.errors[1..]) |err| {13941 for (tree.errors[1..]) |err| {
13937 if (err.is_note) {13942 if (err.is_note) {
13938 try tree.renderError(err, msg.writer(gpa));13943 tree.renderError(err, msg_writer) catch |e| return @errorCast(e); // TODO try @errorCast(...)
13939 try notes.append(gpa, try astgen.errNoteTok(err.token, "{s}", .{msg.items}));13944 try notes.append(gpa, try astgen.errNoteTok(err.token, "{s}", .{msg.getWritten()}));
13940 } else {13945 } else {
13941 // Flush error13946 // Flush error
13942 const extra_offset = tree.errorOffset(cur_err);13947 const extra_offset = tree.errorOffset(cur_err);
13943 try tree.renderError(cur_err, msg.writer(gpa));13948 tree.renderError(cur_err, msg_writer) catch |e| return @errorCast(e); // TODO try @errorCast(...)
13944 try astgen.appendErrorTokNotesOff(cur_err.token, extra_offset, "{s}", .{msg.items}, notes.items);13949 try astgen.appendErrorTokNotesOff(cur_err.token, extra_offset, "{s}", .{msg.getWritten()}, notes.items);
13945 notes.clearRetainingCapacity();13950 notes.clearRetainingCapacity();
13946 cur_err = err;13951 cur_err = err;
1394713952
...@@ -13954,8 +13959,8 @@ fn lowerAstErrors(astgen: *AstGen) !void {...@@ -13954,8 +13959,8 @@ fn lowerAstErrors(astgen: *AstGen) !void {
1395413959
13955 // Flush error13960 // Flush error
13956 const extra_offset = tree.errorOffset(cur_err);13961 const extra_offset = tree.errorOffset(cur_err);
13957 try tree.renderError(cur_err, msg.writer(gpa));13962 tree.renderError(cur_err, msg_writer) catch |e| return @errorCast(e); // TODO try @errorCast(...)
13958 try astgen.appendErrorTokNotesOff(cur_err.token, extra_offset, "{s}", .{msg.items}, notes.items);13963 try astgen.appendErrorTokNotesOff(cur_err.token, extra_offset, "{s}", .{msg.getWritten()}, notes.items);
13959}13964}
1396013965
13961const DeclarationName = union(enum) {13966const DeclarationName = union(enum) {
lib/std/zig/ZonGen.zig+56-49
...@@ -452,37 +452,43 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator...@@ -452,37 +452,43 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator
452 }452 }
453}453}
454454
455fn appendIdentStr(zg: *ZonGen, ident_token: Ast.TokenIndex) !u32 {455fn appendIdentStr(zg: *ZonGen, ident_token: Ast.TokenIndex) error{ OutOfMemory, BadString }!u32 {
456 const gpa = zg.gpa;
456 const tree = zg.tree;457 const tree = zg.tree;
457 assert(tree.tokenTag(ident_token) == .identifier);458 assert(tree.tokenTag(ident_token) == .identifier);
458 const ident_name = tree.tokenSlice(ident_token);459 const ident_name = tree.tokenSlice(ident_token);
459 if (!mem.startsWith(u8, ident_name, "@")) {460 if (!mem.startsWith(u8, ident_name, "@")) {
460 const start = zg.string_bytes.items.len;461 const start = zg.string_bytes.items.len;
461 try zg.string_bytes.appendSlice(zg.gpa, ident_name);462 try zg.string_bytes.appendSlice(gpa, ident_name);
462 return @intCast(start);463 return @intCast(start);
463 } else {464 }
464 const offset = 1;465 const offset = 1;
465 const start: u32 = @intCast(zg.string_bytes.items.len);466 const start: u32 = @intCast(zg.string_bytes.items.len);
466 const raw_string = zg.tree.tokenSlice(ident_token)[offset..];467 const raw_string = zg.tree.tokenSlice(ident_token)[offset..];
467 try zg.string_bytes.ensureUnusedCapacity(zg.gpa, raw_string.len);468 try zg.string_bytes.ensureUnusedCapacity(gpa, raw_string.len);
468 switch (try std.zig.string_literal.parseWrite(zg.string_bytes.writer(zg.gpa), raw_string)) {469 const result = r: {
469 .success => {},470 var aw: std.io.AllocatingWriter = undefined;
470 .failure => |err| {471 const bw = aw.fromArrayList(gpa, &zg.string_bytes);
471 try zg.lowerStrLitError(err, ident_token, raw_string, offset);472 defer zg.string_bytes = aw.toArrayList();
472 return error.BadString;473 break :r std.zig.string_literal.parseWrite(bw, raw_string) catch |err| return @errorCast(err);
473 },474 };
474 }475 switch (result) {
475476 .success => {},
476 const slice = zg.string_bytes.items[start..];477 .failure => |err| {
477 if (mem.indexOfScalar(u8, slice, 0) != null) {478 try zg.lowerStrLitError(err, ident_token, raw_string, offset);
478 try zg.addErrorTok(ident_token, "identifier cannot contain null bytes", .{});
479 return error.BadString;
480 } else if (slice.len == 0) {
481 try zg.addErrorTok(ident_token, "identifier cannot be empty", .{});
482 return error.BadString;479 return error.BadString;
483 }480 },
484 return start;481 }
482
483 const slice = zg.string_bytes.items[start..];
484 if (mem.indexOfScalar(u8, slice, 0) != null) {
485 try zg.addErrorTok(ident_token, "identifier cannot contain null bytes", .{});
486 return error.BadString;
487 } else if (slice.len == 0) {
488 try zg.addErrorTok(ident_token, "identifier cannot be empty", .{});
489 return error.BadString;
485 }490 }
491 return start;
486}492}
487493
488/// Estimates the size of a string node without parsing it.494/// Estimates the size of a string node without parsing it.
...@@ -513,8 +519,8 @@ pub fn strLitSizeHint(tree: Ast, node: Ast.Node.Index) usize {...@@ -513,8 +519,8 @@ pub fn strLitSizeHint(tree: Ast, node: Ast.Node.Index) usize {
513pub fn parseStrLit(519pub fn parseStrLit(
514 tree: Ast,520 tree: Ast,
515 node: Ast.Node.Index,521 node: Ast.Node.Index,
516 writer: anytype,522 writer: *std.io.BufferedWriter,
517) error{OutOfMemory}!std.zig.string_literal.Result {523) anyerror!std.zig.string_literal.Result {
518 switch (tree.nodeTag(node)) {524 switch (tree.nodeTag(node)) {
519 .string_literal => {525 .string_literal => {
520 const token = tree.nodeMainToken(node);526 const token = tree.nodeMainToken(node);
...@@ -549,15 +555,21 @@ const StringLiteralResult = union(enum) {...@@ -549,15 +555,21 @@ const StringLiteralResult = union(enum) {
549 slice: struct { start: u32, len: u32 },555 slice: struct { start: u32, len: u32 },
550};556};
551557
552fn strLitAsString(zg: *ZonGen, str_node: Ast.Node.Index) !StringLiteralResult {558fn strLitAsString(zg: *ZonGen, str_node: Ast.Node.Index) error{ OutOfMemory, BadString }!StringLiteralResult {
553 if (!zg.options.parse_str_lits) return .{ .slice = .{ .start = 0, .len = 0 } };559 if (!zg.options.parse_str_lits) return .{ .slice = .{ .start = 0, .len = 0 } };
554560
555 const gpa = zg.gpa;561 const gpa = zg.gpa;
556 const string_bytes = &zg.string_bytes;562 const string_bytes = &zg.string_bytes;
557 const str_index: u32 = @intCast(zg.string_bytes.items.len);563 const str_index: u32 = @intCast(zg.string_bytes.items.len);
558 const size_hint = strLitSizeHint(zg.tree, str_node);564 const size_hint = strLitSizeHint(zg.tree, str_node);
559 try string_bytes.ensureUnusedCapacity(zg.gpa, size_hint);565 try string_bytes.ensureUnusedCapacity(gpa, size_hint);
560 switch (try parseStrLit(zg.tree, str_node, zg.string_bytes.writer(zg.gpa))) {566 const result = r: {
567 var aw: std.io.AllocatingWriter = undefined;
568 const bw = aw.fromArrayList(gpa, &zg.string_bytes);
569 defer zg.string_bytes = aw.toArrayList();
570 break :r parseStrLit(zg.tree, str_node, bw) catch |err| return @errorCast(err);
571 };
572 switch (result) {
561 .success => {},573 .success => {},
562 .failure => |err| {574 .failure => |err| {
563 const token = zg.tree.nodeMainToken(str_node);575 const token = zg.tree.nodeMainToken(str_node);
...@@ -805,10 +817,7 @@ fn lowerNumberError(zg: *ZonGen, err: std.zig.number_literal.Error, token: Ast.T...@@ -805,10 +817,7 @@ fn lowerNumberError(zg: *ZonGen, err: std.zig.number_literal.Error, token: Ast.T
805817
806fn errNoteNode(zg: *ZonGen, node: Ast.Node.Index, comptime format: []const u8, args: anytype) Allocator.Error!Zoir.CompileError.Note {818fn errNoteNode(zg: *ZonGen, node: Ast.Node.Index, comptime format: []const u8, args: anytype) Allocator.Error!Zoir.CompileError.Note {
807 const message_idx: u32 = @intCast(zg.string_bytes.items.len);819 const message_idx: u32 = @intCast(zg.string_bytes.items.len);
808 const writer = zg.string_bytes.writer(zg.gpa);820 try zg.string_bytes.print(zg.gpa, format ++ "\x00", args);
809 try writer.print(format, args);
810 try writer.writeByte(0);
811
812 return .{821 return .{
813 .msg = @enumFromInt(message_idx),822 .msg = @enumFromInt(message_idx),
814 .token = .none,823 .token = .none,
...@@ -818,10 +827,7 @@ fn errNoteNode(zg: *ZonGen, node: Ast.Node.Index, comptime format: []const u8, a...@@ -818,10 +827,7 @@ fn errNoteNode(zg: *ZonGen, node: Ast.Node.Index, comptime format: []const u8, a
818827
819fn errNoteTok(zg: *ZonGen, tok: Ast.TokenIndex, comptime format: []const u8, args: anytype) Allocator.Error!Zoir.CompileError.Note {828fn errNoteTok(zg: *ZonGen, tok: Ast.TokenIndex, comptime format: []const u8, args: anytype) Allocator.Error!Zoir.CompileError.Note {
820 const message_idx: u32 = @intCast(zg.string_bytes.items.len);829 const message_idx: u32 = @intCast(zg.string_bytes.items.len);
821 const writer = zg.string_bytes.writer(zg.gpa);830 try zg.string_bytes.print(zg.gpa, format ++ "\x00", args);
822 try writer.print(format, args);
823 try writer.writeByte(0);
824
825 return .{831 return .{
826 .msg = @enumFromInt(message_idx),832 .msg = @enumFromInt(message_idx),
827 .token = .fromToken(tok),833 .token = .fromToken(tok),
...@@ -862,9 +868,7 @@ fn addErrorInner(...@@ -862,9 +868,7 @@ fn addErrorInner(
862 try zg.error_notes.appendSlice(gpa, notes);868 try zg.error_notes.appendSlice(gpa, notes);
863869
864 const message_idx: u32 = @intCast(zg.string_bytes.items.len);870 const message_idx: u32 = @intCast(zg.string_bytes.items.len);
865 const writer = zg.string_bytes.writer(zg.gpa);871 try zg.string_bytes.print(gpa, format ++ "\x00", args);
866 try writer.print(format, args);
867 try writer.writeByte(0);
868872
869 try zg.compile_errors.append(gpa, .{873 try zg.compile_errors.append(gpa, .{
870 .msg = @enumFromInt(message_idx),874 .msg = @enumFromInt(message_idx),
...@@ -880,8 +884,9 @@ fn lowerAstErrors(zg: *ZonGen) Allocator.Error!void {...@@ -880,8 +884,9 @@ fn lowerAstErrors(zg: *ZonGen) Allocator.Error!void {
880 const tree = zg.tree;884 const tree = zg.tree;
881 assert(tree.errors.len > 0);885 assert(tree.errors.len > 0);
882886
883 var msg: std.ArrayListUnmanaged(u8) = .empty;887 var msg: std.io.AllocatingWriter = undefined;
884 defer msg.deinit(gpa);888 const msg_bw = msg.init(gpa);
889 defer msg.deinit();
885890
886 var notes: std.ArrayListUnmanaged(Zoir.CompileError.Note) = .empty;891 var notes: std.ArrayListUnmanaged(Zoir.CompileError.Note) = .empty;
887 defer notes.deinit(gpa);892 defer notes.deinit(gpa);
...@@ -889,18 +894,20 @@ fn lowerAstErrors(zg: *ZonGen) Allocator.Error!void {...@@ -889,18 +894,20 @@ fn lowerAstErrors(zg: *ZonGen) Allocator.Error!void {
889 var cur_err = tree.errors[0];894 var cur_err = tree.errors[0];
890 for (tree.errors[1..]) |err| {895 for (tree.errors[1..]) |err| {
891 if (err.is_note) {896 if (err.is_note) {
892 try tree.renderError(err, msg.writer(gpa));897 tree.renderError(err, msg_bw) catch |e| return @errorCast(e); // TODO: try @errorCast(...)
893 try notes.append(gpa, try zg.errNoteTok(err.token, "{s}", .{msg.items}));898 try notes.append(gpa, try zg.errNoteTok(err.token, "{s}", .{msg.getWritten()}));
894 } else {899 } else {
895 // Flush error900 // Flush error
896 try tree.renderError(cur_err, msg.writer(gpa));901 tree.renderError(cur_err, msg_bw) catch |e| return @errorCast(e); // TODO try @errorCast(...)
897 const extra_offset = tree.errorOffset(cur_err);902 const extra_offset = tree.errorOffset(cur_err);
898 try zg.addErrorTokNotesOff(cur_err.token, extra_offset, "{s}", .{msg.items}, notes.items);903 try zg.addErrorTokNotesOff(cur_err.token, extra_offset, "{s}", .{msg.getWritten()}, notes.items);
899 notes.clearRetainingCapacity();904 notes.clearRetainingCapacity();
900 cur_err = err;905 cur_err = err;
901906
902 // TODO: `Parse` currently does not have good error recovery mechanisms, so the remaining errors could be bogus.907 // TODO: `Parse` currently does not have good error recovery
903 // As such, we'll ignore all remaining errors for now. We should improve `Parse` so that we can report all the errors.908 // mechanisms, so the remaining errors could be bogus. As such,
909 // we'll ignore all remaining errors for now. We should improve
910 // `Parse` so that we can report all the errors.
904 return;911 return;
905 }912 }
906 msg.clearRetainingCapacity();913 msg.clearRetainingCapacity();
...@@ -908,8 +915,8 @@ fn lowerAstErrors(zg: *ZonGen) Allocator.Error!void {...@@ -908,8 +915,8 @@ fn lowerAstErrors(zg: *ZonGen) Allocator.Error!void {
908915
909 // Flush error916 // Flush error
910 const extra_offset = tree.errorOffset(cur_err);917 const extra_offset = tree.errorOffset(cur_err);
911 try tree.renderError(cur_err, msg.writer(gpa));918 tree.renderError(cur_err, msg_bw) catch |e| return @errorCast(e); // TODO try @errorCast(...)
912 try zg.addErrorTokNotesOff(cur_err.token, extra_offset, "{s}", .{msg.items}, notes.items);919 try zg.addErrorTokNotesOff(cur_err.token, extra_offset, "{s}", .{msg.getWritten()}, notes.items);
913}920}
914921
915const std = @import("std");922const std = @import("std");
lib/std/zig/render.zig+297-291
...@@ -10,10 +10,6 @@ const primitives = std.zig.primitives;...@@ -10,10 +10,6 @@ const primitives = std.zig.primitives;
10const indent_delta = 4;10const indent_delta = 4;
11const asm_indent_delta = 2;11const asm_indent_delta = 2;
1212
13pub const Error = Ast.RenderError;
14
15const Ais = AutoIndentingStream(std.ArrayList(u8).Writer);
16
17pub const Fixups = struct {13pub const Fixups = struct {
18 /// The key is the mut token (`var`/`const`) of the variable declaration14 /// The key is the mut token (`var`/`const`) of the variable declaration
19 /// that should have a `_ = foo;` inserted afterwards.15 /// that should have a `_ = foo;` inserted afterwards.
...@@ -74,17 +70,17 @@ pub const Fixups = struct {...@@ -74,17 +70,17 @@ pub const Fixups = struct {
7470
75const Render = struct {71const Render = struct {
76 gpa: Allocator,72 gpa: Allocator,
77 ais: *Ais,73 ais: *AutoIndentingStream,
78 tree: Ast,74 tree: Ast,
79 fixups: Fixups,75 fixups: Fixups,
80};76};
8177
82pub fn renderTree(buffer: *std.ArrayList(u8), tree: Ast, fixups: Fixups) Error!void {78pub fn renderTree(gpa: Allocator, bw: *std.io.BufferedWriter, tree: Ast, fixups: Fixups) anyerror!void {
83 assert(tree.errors.len == 0); // Cannot render an invalid tree.79 assert(tree.errors.len == 0); // Cannot render an invalid tree.
84 var auto_indenting_stream = Ais.init(buffer, indent_delta);80 var auto_indenting_stream: AutoIndentingStream = .init(bw, indent_delta);
85 defer auto_indenting_stream.deinit();81 defer auto_indenting_stream.deinit();
86 var r: Render = .{82 var r: Render = .{
87 .gpa = buffer.allocator,83 .gpa = gpa,
88 .ais = &auto_indenting_stream,84 .ais = &auto_indenting_stream,
89 .tree = tree,85 .tree = tree,
90 .fixups = fixups,86 .fixups = fixups,
...@@ -115,7 +111,7 @@ pub fn renderTree(buffer: *std.ArrayList(u8), tree: Ast, fixups: Fixups) Error!v...@@ -115,7 +111,7 @@ pub fn renderTree(buffer: *std.ArrayList(u8), tree: Ast, fixups: Fixups) Error!v
115}111}
116112
117/// Render all members in the given slice, keeping empty lines where appropriate113/// Render all members in the given slice, keeping empty lines where appropriate
118fn renderMembers(r: *Render, members: []const Ast.Node.Index) Error!void {114fn renderMembers(r: *Render, members: []const Ast.Node.Index) anyerror!void {
119 const tree = r.tree;115 const tree = r.tree;
120 if (members.len == 0) return;116 if (members.len == 0) return;
121 const container: Container = for (members) |member| {117 const container: Container = for (members) |member| {
...@@ -139,7 +135,7 @@ fn renderMember(...@@ -139,7 +135,7 @@ fn renderMember(
139 container: Container,135 container: Container,
140 decl: Ast.Node.Index,136 decl: Ast.Node.Index,
141 space: Space,137 space: Space,
142) Error!void {138) anyerror!void {
143 const tree = r.tree;139 const tree = r.tree;
144 const ais = r.ais;140 const ais = r.ais;
145 if (r.fixups.omit_nodes.contains(decl)) return;141 if (r.fixups.omit_nodes.contains(decl)) return;
...@@ -186,7 +182,7 @@ fn renderMember(...@@ -186,7 +182,7 @@ fn renderMember(
186 if (opt_callconv_expr.unwrap()) |callconv_expr| {182 if (opt_callconv_expr.unwrap()) |callconv_expr| {
187 if (tree.nodeTag(callconv_expr) == .enum_literal) {183 if (tree.nodeTag(callconv_expr) == .enum_literal) {
188 if (mem.eql(u8, "@\"inline\"", tree.tokenSlice(tree.nodeMainToken(callconv_expr)))) {184 if (mem.eql(u8, "@\"inline\"", tree.tokenSlice(tree.nodeMainToken(callconv_expr)))) {
189 try ais.writer().writeAll("inline ");185 try ais.underlying_writer.writeAll("inline ");
190 }186 }
191 }187 }
192 }188 }
...@@ -200,7 +196,7 @@ fn renderMember(...@@ -200,7 +196,7 @@ fn renderMember(
200 const lbrace = tree.nodeMainToken(body_node);196 const lbrace = tree.nodeMainToken(body_node);
201 try renderToken(r, lbrace, .newline);197 try renderToken(r, lbrace, .newline);
202 try discardAllParams(r, fn_proto);198 try discardAllParams(r, fn_proto);
203 try ais.writer().writeAll("@trap();");199 try ais.writeAll("@trap();");
204 ais.popIndent();200 ais.popIndent();
205 try ais.insertNewline();201 try ais.insertNewline();
206 try renderToken(r, tree.lastToken(body_node), space); // rbrace202 try renderToken(r, tree.lastToken(body_node), space); // rbrace
...@@ -216,10 +212,9 @@ fn renderMember(...@@ -216,10 +212,9 @@ fn renderMember(
216 const name_ident = param.name_token.?;212 const name_ident = param.name_token.?;
217 assert(tree.tokenTag(name_ident) == .identifier);213 assert(tree.tokenTag(name_ident) == .identifier);
218 if (r.fixups.unused_var_decls.contains(name_ident)) {214 if (r.fixups.unused_var_decls.contains(name_ident)) {
219 const w = ais.writer();215 try ais.writeAll("_ = ");
220 try w.writeAll("_ = ");216 try ais.writeAll(tokenSliceForRender(r.tree, name_ident));
221 try w.writeAll(tokenSliceForRender(r.tree, name_ident));217 try ais.writeAll(";\n");
222 try w.writeAll(";\n");
223 }218 }
224 }219 }
225 var statements_buf: [2]Ast.Node.Index = undefined;220 var statements_buf: [2]Ast.Node.Index = undefined;
...@@ -310,7 +305,7 @@ fn renderMember(...@@ -310,7 +305,7 @@ fn renderMember(
310}305}
311306
312/// Render all expressions in the slice, keeping empty lines where appropriate307/// Render all expressions in the slice, keeping empty lines where appropriate
313fn renderExpressions(r: *Render, expressions: []const Ast.Node.Index, space: Space) Error!void {308fn renderExpressions(r: *Render, expressions: []const Ast.Node.Index, space: Space) anyerror!void {
314 if (expressions.len == 0) return;309 if (expressions.len == 0) return;
315 try renderExpression(r, expressions[0], space);310 try renderExpression(r, expressions[0], space);
316 for (expressions[1..]) |expression| {311 for (expressions[1..]) |expression| {
...@@ -319,11 +314,11 @@ fn renderExpressions(r: *Render, expressions: []const Ast.Node.Index, space: Spa...@@ -319,11 +314,11 @@ fn renderExpressions(r: *Render, expressions: []const Ast.Node.Index, space: Spa
319 }314 }
320}315}
321316
322fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {317fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) anyerror!void {
323 const tree = r.tree;318 const tree = r.tree;
324 const ais = r.ais;319 const ais = r.ais;
325 if (r.fixups.replace_nodes_with_string.get(node)) |replacement| {320 if (r.fixups.replace_nodes_with_string.get(node)) |replacement| {
326 try ais.writer().writeAll(replacement);321 try ais.writeAll(replacement);
327 try renderOnlySpace(r, space);322 try renderOnlySpace(r, space);
328 return;323 return;
329 } else if (r.fixups.replace_nodes_with_node.get(node)) |replacement| {324 } else if (r.fixups.replace_nodes_with_node.get(node)) |replacement| {
...@@ -891,11 +886,11 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {...@@ -891,11 +886,11 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {
891886
892/// Same as `renderExpression`, but afterwards looks for any887/// Same as `renderExpression`, but afterwards looks for any
893/// append_string_after_node fixups to apply888/// append_string_after_node fixups to apply
894fn renderExpressionFixup(r: *Render, node: Ast.Node.Index, space: Space) Error!void {889fn renderExpressionFixup(r: *Render, node: Ast.Node.Index, space: Space) anyerror!void {
895 const ais = r.ais;890 const ais = r.ais;
896 try renderExpression(r, node, space);891 try renderExpression(r, node, space);
897 if (r.fixups.append_string_after_node.get(node)) |bytes| {892 if (r.fixups.append_string_after_node.get(node)) |bytes| {
898 try ais.writer().writeAll(bytes);893 try ais.writeAll(bytes);
899 }894 }
900}895}
901896
...@@ -903,7 +898,7 @@ fn renderArrayType(...@@ -903,7 +898,7 @@ fn renderArrayType(
903 r: *Render,898 r: *Render,
904 array_type: Ast.full.ArrayType,899 array_type: Ast.full.ArrayType,
905 space: Space,900 space: Space,
906) Error!void {901) anyerror!void {
907 const tree = r.tree;902 const tree = r.tree;
908 const ais = r.ais;903 const ais = r.ais;
909 const rbracket = tree.firstToken(array_type.ast.elem_type) - 1;904 const rbracket = tree.firstToken(array_type.ast.elem_type) - 1;
...@@ -921,7 +916,7 @@ fn renderArrayType(...@@ -921,7 +916,7 @@ fn renderArrayType(
921 return renderExpression(r, array_type.ast.elem_type, space);916 return renderExpression(r, array_type.ast.elem_type, space);
922}917}
923918
924fn renderPtrType(r: *Render, ptr_type: Ast.full.PtrType, space: Space) Error!void {919fn renderPtrType(r: *Render, ptr_type: Ast.full.PtrType, space: Space) anyerror!void {
925 const tree = r.tree;920 const tree = r.tree;
926 const main_token = ptr_type.ast.main_token;921 const main_token = ptr_type.ast.main_token;
927 switch (ptr_type.size) {922 switch (ptr_type.size) {
...@@ -1015,7 +1010,7 @@ fn renderSlice(...@@ -1015,7 +1010,7 @@ fn renderSlice(
1015 slice_node: Ast.Node.Index,1010 slice_node: Ast.Node.Index,
1016 slice: Ast.full.Slice,1011 slice: Ast.full.Slice,
1017 space: Space,1012 space: Space,
1018) Error!void {1013) anyerror!void {
1019 const tree = r.tree;1014 const tree = r.tree;
1020 const after_start_space_bool = nodeCausesSliceOpSpace(tree.nodeTag(slice.ast.start)) or1015 const after_start_space_bool = nodeCausesSliceOpSpace(tree.nodeTag(slice.ast.start)) or
1021 if (slice.ast.end.unwrap()) |end| nodeCausesSliceOpSpace(tree.nodeTag(end)) else false;1016 if (slice.ast.end.unwrap()) |end| nodeCausesSliceOpSpace(tree.nodeTag(end)) else false;
...@@ -1048,7 +1043,7 @@ fn renderAsmOutput(...@@ -1048,7 +1043,7 @@ fn renderAsmOutput(
1048 r: *Render,1043 r: *Render,
1049 asm_output: Ast.Node.Index,1044 asm_output: Ast.Node.Index,
1050 space: Space,1045 space: Space,
1051) Error!void {1046) anyerror!void {
1052 const tree = r.tree;1047 const tree = r.tree;
1053 assert(tree.nodeTag(asm_output) == .asm_output);1048 assert(tree.nodeTag(asm_output) == .asm_output);
1054 const symbolic_name = tree.nodeMainToken(asm_output);1049 const symbolic_name = tree.nodeMainToken(asm_output);
...@@ -1074,7 +1069,7 @@ fn renderAsmInput(...@@ -1074,7 +1069,7 @@ fn renderAsmInput(
1074 r: *Render,1069 r: *Render,
1075 asm_input: Ast.Node.Index,1070 asm_input: Ast.Node.Index,
1076 space: Space,1071 space: Space,
1077) Error!void {1072) anyerror!void {
1078 const tree = r.tree;1073 const tree = r.tree;
1079 assert(tree.nodeTag(asm_input) == .asm_input);1074 assert(tree.nodeTag(asm_input) == .asm_input);
1080 const symbolic_name = tree.nodeMainToken(asm_input);1075 const symbolic_name = tree.nodeMainToken(asm_input);
...@@ -1096,14 +1091,14 @@ fn renderVarDecl(...@@ -1096,14 +1091,14 @@ fn renderVarDecl(
1096 ignore_comptime_token: bool,1091 ignore_comptime_token: bool,
1097 /// `comma_space` and `space` are used for destructure LHS decls.1092 /// `comma_space` and `space` are used for destructure LHS decls.
1098 space: Space,1093 space: Space,
1099) Error!void {1094) anyerror!void {
1100 try renderVarDeclWithoutFixups(r, var_decl, ignore_comptime_token, space);1095 try renderVarDeclWithoutFixups(r, var_decl, ignore_comptime_token, space);
1101 if (r.fixups.unused_var_decls.contains(var_decl.ast.mut_token + 1)) {1096 if (r.fixups.unused_var_decls.contains(var_decl.ast.mut_token + 1)) {
1102 // Discard the variable like this: `_ = foo;`1097 // Discard the variable like this: `_ = foo;`
1103 const w = r.ais.writer();1098 const ais = r.ais;
1104 try w.writeAll("_ = ");1099 try ais.writeAll("_ = ");
1105 try w.writeAll(tokenSliceForRender(r.tree, var_decl.ast.mut_token + 1));1100 try ais.writeAll(tokenSliceForRender(r.tree, var_decl.ast.mut_token + 1));
1106 try w.writeAll(";\n");1101 try ais.writeAll(";\n");
1107 }1102 }
1108}1103}
11091104
...@@ -1114,7 +1109,7 @@ fn renderVarDeclWithoutFixups(...@@ -1114,7 +1109,7 @@ fn renderVarDeclWithoutFixups(
1114 ignore_comptime_token: bool,1109 ignore_comptime_token: bool,
1115 /// `comma_space` and `space` are used for destructure LHS decls.1110 /// `comma_space` and `space` are used for destructure LHS decls.
1116 space: Space,1111 space: Space,
1117) Error!void {1112) anyerror!void {
1118 const tree = r.tree;1113 const tree = r.tree;
1119 const ais = r.ais;1114 const ais = r.ais;
11201115
...@@ -1226,7 +1221,7 @@ fn renderVarDeclWithoutFixups(...@@ -1226,7 +1221,7 @@ fn renderVarDeclWithoutFixups(
1226 ais.popIndent();1221 ais.popIndent();
1227}1222}
12281223
1229fn renderIf(r: *Render, if_node: Ast.full.If, space: Space) Error!void {1224fn renderIf(r: *Render, if_node: Ast.full.If, space: Space) anyerror!void {
1230 return renderWhile(r, .{1225 return renderWhile(r, .{
1231 .ast = .{1226 .ast = .{
1232 .while_token = if_node.ast.if_token,1227 .while_token = if_node.ast.if_token,
...@@ -1245,7 +1240,7 @@ fn renderIf(r: *Render, if_node: Ast.full.If, space: Space) Error!void {...@@ -1245,7 +1240,7 @@ fn renderIf(r: *Render, if_node: Ast.full.If, space: Space) Error!void {
12451240
1246/// Note that this function is additionally used to render if expressions, with1241/// Note that this function is additionally used to render if expressions, with
1247/// respective values set to null.1242/// respective values set to null.
1248fn renderWhile(r: *Render, while_node: Ast.full.While, space: Space) Error!void {1243fn renderWhile(r: *Render, while_node: Ast.full.While, space: Space) anyerror!void {
1249 const tree = r.tree;1244 const tree = r.tree;
12501245
1251 if (while_node.label_token) |label| {1246 if (while_node.label_token) |label| {
...@@ -1315,7 +1310,7 @@ fn renderThenElse(...@@ -1315,7 +1310,7 @@ fn renderThenElse(
1315 maybe_error_token: ?Ast.TokenIndex,1310 maybe_error_token: ?Ast.TokenIndex,
1316 opt_else_expr: Ast.Node.OptionalIndex,1311 opt_else_expr: Ast.Node.OptionalIndex,
1317 space: Space,1312 space: Space,
1318) Error!void {1313) anyerror!void {
1319 const tree = r.tree;1314 const tree = r.tree;
1320 const ais = r.ais;1315 const ais = r.ais;
1321 const then_expr_is_block = nodeIsBlock(tree.nodeTag(then_expr));1316 const then_expr_is_block = nodeIsBlock(tree.nodeTag(then_expr));
...@@ -1370,7 +1365,7 @@ fn renderThenElse(...@@ -1370,7 +1365,7 @@ fn renderThenElse(
1370 }1365 }
1371}1366}
13721367
1373fn renderFor(r: *Render, for_node: Ast.full.For, space: Space) Error!void {1368fn renderFor(r: *Render, for_node: Ast.full.For, space: Space) anyerror!void {
1374 const tree = r.tree;1369 const tree = r.tree;
1375 const ais = r.ais;1370 const ais = r.ais;
1376 const token_tags = tree.tokens.items(.tag);1371 const token_tags = tree.tokens.items(.tag);
...@@ -1445,7 +1440,7 @@ fn renderContainerField(...@@ -1445,7 +1440,7 @@ fn renderContainerField(
1445 container: Container,1440 container: Container,
1446 field_param: Ast.full.ContainerField,1441 field_param: Ast.full.ContainerField,
1447 space: Space,1442 space: Space,
1448) Error!void {1443) anyerror!void {
1449 const tree = r.tree;1444 const tree = r.tree;
1450 const ais = r.ais;1445 const ais = r.ais;
1451 var field = field_param;1446 var field = field_param;
...@@ -1554,7 +1549,7 @@ fn renderBuiltinCall(...@@ -1554,7 +1549,7 @@ fn renderBuiltinCall(
1554 builtin_token: Ast.TokenIndex,1549 builtin_token: Ast.TokenIndex,
1555 params: []const Ast.Node.Index,1550 params: []const Ast.Node.Index,
1556 space: Space,1551 space: Space,
1557) Error!void {1552) anyerror!void {
1558 const tree = r.tree;1553 const tree = r.tree;
1559 const ais = r.ais;1554 const ais = r.ais;
15601555
...@@ -1581,7 +1576,7 @@ fn renderBuiltinCall(...@@ -1581,7 +1576,7 @@ fn renderBuiltinCall(
1581 defer r.gpa.free(new_string);1576 defer r.gpa.free(new_string);
15821577
1583 try renderToken(r, builtin_token + 1, .none); // (1578 try renderToken(r, builtin_token + 1, .none); // (
1584 try ais.writer().print("\"{}\"", .{std.zig.fmtEscapes(new_string)});1579 try ais.print("\"{}\"", .{std.zig.fmtEscapes(new_string)});
1585 return renderToken(r, str_lit_token + 1, space); // )1580 return renderToken(r, str_lit_token + 1, space); // )
1586 }1581 }
1587 }1582 }
...@@ -1627,7 +1622,7 @@ fn renderBuiltinCall(...@@ -1627,7 +1622,7 @@ fn renderBuiltinCall(
1627 }1622 }
1628}1623}
16291624
1630fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!void {1625fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) anyerror!void {
1631 const tree = r.tree;1626 const tree = r.tree;
1632 const ais = r.ais;1627 const ais = r.ais;
16331628
...@@ -1852,7 +1847,7 @@ fn renderSwitchCase(...@@ -1852,7 +1847,7 @@ fn renderSwitchCase(
1852 r: *Render,1847 r: *Render,
1853 switch_case: Ast.full.SwitchCase,1848 switch_case: Ast.full.SwitchCase,
1854 space: Space,1849 space: Space,
1855) Error!void {1850) anyerror!void {
1856 const ais = r.ais;1851 const ais = r.ais;
1857 const tree = r.tree;1852 const tree = r.tree;
1858 const trailing_comma = tree.tokenTag(switch_case.ast.arrow_token - 1) == .comma;1853 const trailing_comma = tree.tokenTag(switch_case.ast.arrow_token - 1) == .comma;
...@@ -1914,7 +1909,7 @@ fn renderBlock(...@@ -1914,7 +1909,7 @@ fn renderBlock(
1914 block_node: Ast.Node.Index,1909 block_node: Ast.Node.Index,
1915 statements: []const Ast.Node.Index,1910 statements: []const Ast.Node.Index,
1916 space: Space,1911 space: Space,
1917) Error!void {1912) anyerror!void {
1918 const tree = r.tree;1913 const tree = r.tree;
1919 const ais = r.ais;1914 const ais = r.ais;
1920 const lbrace = tree.nodeMainToken(block_node);1915 const lbrace = tree.nodeMainToken(block_node);
...@@ -1939,7 +1934,7 @@ fn finishRenderBlock(...@@ -1939,7 +1934,7 @@ fn finishRenderBlock(
1939 block_node: Ast.Node.Index,1934 block_node: Ast.Node.Index,
1940 statements: []const Ast.Node.Index,1935 statements: []const Ast.Node.Index,
1941 space: Space,1936 space: Space,
1942) Error!void {1937) anyerror!void {
1943 const tree = r.tree;1938 const tree = r.tree;
1944 const ais = r.ais;1939 const ais = r.ais;
1945 for (statements, 0..) |stmt, i| {1940 for (statements, 0..) |stmt, i| {
...@@ -1967,7 +1962,7 @@ fn renderStructInit(...@@ -1967,7 +1962,7 @@ fn renderStructInit(
1967 struct_node: Ast.Node.Index,1962 struct_node: Ast.Node.Index,
1968 struct_init: Ast.full.StructInit,1963 struct_init: Ast.full.StructInit,
1969 space: Space,1964 space: Space,
1970) Error!void {1965) anyerror!void {
1971 const tree = r.tree;1966 const tree = r.tree;
1972 const ais = r.ais;1967 const ais = r.ais;
19731968
...@@ -2038,7 +2033,7 @@ fn renderArrayInit(...@@ -2038,7 +2033,7 @@ fn renderArrayInit(
2038 r: *Render,2033 r: *Render,
2039 array_init: Ast.full.ArrayInit,2034 array_init: Ast.full.ArrayInit,
2040 space: Space,2035 space: Space,
2041) Error!void {2036) anyerror!void {
2042 const tree = r.tree;2037 const tree = r.tree;
2043 const ais = r.ais;2038 const ais = r.ais;
2044 const gpa = r.gpa;2039 const gpa = r.gpa;
...@@ -2139,13 +2134,14 @@ fn renderArrayInit(...@@ -2139,13 +2134,14 @@ fn renderArrayInit(
21392134
2140 const section_exprs = row_exprs[0..section_end];2135 const section_exprs = row_exprs[0..section_end];
21412136
2142 var sub_expr_buffer = std.ArrayList(u8).init(gpa);2137 var sub_expr_buffer: std.io.AllocatingWriter = undefined;
2138 const sub_expr_buffer_writer = sub_expr_buffer.init(gpa);
2143 defer sub_expr_buffer.deinit();2139 defer sub_expr_buffer.deinit();
21442140
2145 const sub_expr_buffer_starts = try gpa.alloc(usize, section_exprs.len + 1);2141 const sub_expr_buffer_starts = try gpa.alloc(usize, section_exprs.len + 1);
2146 defer gpa.free(sub_expr_buffer_starts);2142 defer gpa.free(sub_expr_buffer_starts);
21472143
2148 var auto_indenting_stream = Ais.init(&sub_expr_buffer, indent_delta);2144 var auto_indenting_stream: AutoIndentingStream = .init(sub_expr_buffer_writer, indent_delta);
2149 defer auto_indenting_stream.deinit();2145 defer auto_indenting_stream.deinit();
2150 var sub_render: Render = .{2146 var sub_render: Render = .{
2151 .gpa = r.gpa,2147 .gpa = r.gpa,
...@@ -2159,13 +2155,13 @@ fn renderArrayInit(...@@ -2159,13 +2155,13 @@ fn renderArrayInit(
2159 var single_line = true;2155 var single_line = true;
2160 var contains_newline = false;2156 var contains_newline = false;
2161 for (section_exprs, 0..) |expr, i| {2157 for (section_exprs, 0..) |expr, i| {
2162 const start = sub_expr_buffer.items.len;2158 const start = sub_expr_buffer.getWritten().len;
2163 sub_expr_buffer_starts[i] = start;2159 sub_expr_buffer_starts[i] = start;
21642160
2165 if (i + 1 < section_exprs.len) {2161 if (i + 1 < section_exprs.len) {
2166 try renderExpression(&sub_render, expr, .none);2162 try renderExpression(&sub_render, expr, .none);
2167 const width = sub_expr_buffer.items.len - start;2163 const width = sub_expr_buffer.getWritten().len - start;
2168 const this_contains_newline = mem.indexOfScalar(u8, sub_expr_buffer.items[start..], '\n') != null;2164 const this_contains_newline = mem.indexOfScalar(u8, sub_expr_buffer.getWritten()[start..], '\n') != null;
2169 contains_newline = contains_newline or this_contains_newline;2165 contains_newline = contains_newline or this_contains_newline;
2170 expr_widths[i] = width;2166 expr_widths[i] = width;
2171 expr_newlines[i] = this_contains_newline;2167 expr_newlines[i] = this_contains_newline;
...@@ -2188,7 +2184,7 @@ fn renderArrayInit(...@@ -2188,7 +2184,7 @@ fn renderArrayInit(
2188 ais.popSpace();2184 ais.popSpace();
21892185
2190 const width = sub_expr_buffer.items.len - start - 2;2186 const width = sub_expr_buffer.items.len - start - 2;
2191 const this_contains_newline = mem.indexOfScalar(u8, sub_expr_buffer.items[start .. sub_expr_buffer.items.len - 1], '\n') != null;2187 const this_contains_newline = mem.indexOfScalar(u8, sub_expr_buffer.getWritten()[start .. sub_expr_buffer.items.len - 1], '\n') != null;
2192 contains_newline = contains_newline or this_contains_newline;2188 contains_newline = contains_newline or this_contains_newline;
2193 expr_widths[i] = width;2189 expr_widths[i] = width;
2194 expr_newlines[i] = contains_newline;2190 expr_newlines[i] = contains_newline;
...@@ -2199,20 +2195,20 @@ fn renderArrayInit(...@@ -2199,20 +2195,20 @@ fn renderArrayInit(
2199 }2195 }
2200 }2196 }
2201 }2197 }
2202 sub_expr_buffer_starts[section_exprs.len] = sub_expr_buffer.items.len;2198 sub_expr_buffer_starts[section_exprs.len] = sub_expr_buffer.getWritten().len;
22032199
2204 // Render exprs in current section.2200 // Render exprs in current section.
2205 column_counter = 0;2201 column_counter = 0;
2206 for (section_exprs, 0..) |expr, i| {2202 for (section_exprs, 0..) |expr, i| {
2207 const start = sub_expr_buffer_starts[i];2203 const start = sub_expr_buffer_starts[i];
2208 const end = sub_expr_buffer_starts[i + 1];2204 const end = sub_expr_buffer_starts[i + 1];
2209 const expr_text = sub_expr_buffer.items[start..end];2205 const expr_text = sub_expr_buffer.getWritten()[start..end];
2210 if (!expr_newlines[i]) {2206 if (!expr_newlines[i]) {
2211 try ais.writer().writeAll(expr_text);2207 try ais.writeAll(expr_text);
2212 } else {2208 } else {
2213 var by_line = std.mem.splitScalar(u8, expr_text, '\n');2209 var by_line = std.mem.splitScalar(u8, expr_text, '\n');
2214 var last_line_was_empty = false;2210 var last_line_was_empty = false;
2215 try ais.writer().writeAll(by_line.first());2211 try ais.writeAll(by_line.first());
2216 while (by_line.next()) |line| {2212 while (by_line.next()) |line| {
2217 if (std.mem.startsWith(u8, line, "//") and last_line_was_empty) {2213 if (std.mem.startsWith(u8, line, "//") and last_line_was_empty) {
2218 try ais.insertNewline();2214 try ais.insertNewline();
...@@ -2220,7 +2216,7 @@ fn renderArrayInit(...@@ -2220,7 +2216,7 @@ fn renderArrayInit(
2220 try ais.maybeInsertNewline();2216 try ais.maybeInsertNewline();
2221 }2217 }
2222 last_line_was_empty = (line.len == 0);2218 last_line_was_empty = (line.len == 0);
2223 try ais.writer().writeAll(line);2219 try ais.writeAll(line);
2224 }2220 }
2225 }2221 }
22262222
...@@ -2234,7 +2230,7 @@ fn renderArrayInit(...@@ -2234,7 +2230,7 @@ fn renderArrayInit(
2234 try renderToken(r, comma, .space); // ,2230 try renderToken(r, comma, .space); // ,
2235 assert(column_widths[column_counter % row_size] >= expr_widths[i]);2231 assert(column_widths[column_counter % row_size] >= expr_widths[i]);
2236 const padding = column_widths[column_counter % row_size] - expr_widths[i];2232 const padding = column_widths[column_counter % row_size] - expr_widths[i];
2237 try ais.writer().writeByteNTimes(' ', padding);2233 try ais.splatByteAll(' ', padding);
22382234
2239 column_counter += 1;2235 column_counter += 1;
2240 continue;2236 continue;
...@@ -2265,7 +2261,7 @@ fn renderContainerDecl(...@@ -2265,7 +2261,7 @@ fn renderContainerDecl(
2265 container_decl_node: Ast.Node.Index,2261 container_decl_node: Ast.Node.Index,
2266 container_decl: Ast.full.ContainerDecl,2262 container_decl: Ast.full.ContainerDecl,
2267 space: Space,2263 space: Space,
2268) Error!void {2264) anyerror!void {
2269 const tree = r.tree;2265 const tree = r.tree;
2270 const ais = r.ais;2266 const ais = r.ais;
22712267
...@@ -2384,7 +2380,7 @@ fn renderAsm(...@@ -2384,7 +2380,7 @@ fn renderAsm(
2384 r: *Render,2380 r: *Render,
2385 asm_node: Ast.full.Asm,2381 asm_node: Ast.full.Asm,
2386 space: Space,2382 space: Space,
2387) Error!void {2383) anyerror!void {
2388 const tree = r.tree;2384 const tree = r.tree;
2389 const ais = r.ais;2385 const ais = r.ais;
23902386
...@@ -2550,7 +2546,7 @@ fn renderCall(...@@ -2550,7 +2546,7 @@ fn renderCall(
2550 r: *Render,2546 r: *Render,
2551 call: Ast.full.Call,2547 call: Ast.full.Call,
2552 space: Space,2548 space: Space,
2553) Error!void {2549) anyerror!void {
2554 if (call.async_token) |async_token| {2550 if (call.async_token) |async_token| {
2555 try renderToken(r, async_token, .space);2551 try renderToken(r, async_token, .space);
2556 }2552 }
...@@ -2563,7 +2559,7 @@ fn renderParamList(...@@ -2563,7 +2559,7 @@ fn renderParamList(
2563 lparen: Ast.TokenIndex,2559 lparen: Ast.TokenIndex,
2564 params: []const Ast.Node.Index,2560 params: []const Ast.Node.Index,
2565 space: Space,2561 space: Space,
2566) Error!void {2562) anyerror!void {
2567 const tree = r.tree;2563 const tree = r.tree;
2568 const ais = r.ais;2564 const ais = r.ais;
25692565
...@@ -2616,7 +2612,7 @@ fn renderParamList(...@@ -2616,7 +2612,7 @@ fn renderParamList(
26162612
2617/// Render an expression, and the comma that follows it, if it is present in the source.2613/// Render an expression, and the comma that follows it, if it is present in the source.
2618/// If a comma is present, and `space` is `Space.comma`, render only a single comma.2614/// If a comma is present, and `space` is `Space.comma`, render only a single comma.
2619fn renderExpressionComma(r: *Render, node: Ast.Node.Index, space: Space) Error!void {2615fn renderExpressionComma(r: *Render, node: Ast.Node.Index, space: Space) anyerror!void {
2620 const tree = r.tree;2616 const tree = r.tree;
2621 const maybe_comma = tree.lastToken(node) + 1;2617 const maybe_comma = tree.lastToken(node) + 1;
2622 if (tree.tokenTag(maybe_comma) == .comma and space != .comma) {2618 if (tree.tokenTag(maybe_comma) == .comma and space != .comma) {
...@@ -2629,7 +2625,7 @@ fn renderExpressionComma(r: *Render, node: Ast.Node.Index, space: Space) Error!v...@@ -2629,7 +2625,7 @@ fn renderExpressionComma(r: *Render, node: Ast.Node.Index, space: Space) Error!v
26292625
2630/// Render a token, and the comma that follows it, if it is present in the source.2626/// Render a token, and the comma that follows it, if it is present in the source.
2631/// If a comma is present, and `space` is `Space.comma`, render only a single comma.2627/// If a comma is present, and `space` is `Space.comma`, render only a single comma.
2632fn renderTokenComma(r: *Render, token: Ast.TokenIndex, space: Space) Error!void {2628fn renderTokenComma(r: *Render, token: Ast.TokenIndex, space: Space) anyerror!void {
2633 const tree = r.tree;2629 const tree = r.tree;
2634 const maybe_comma = token + 1;2630 const maybe_comma = token + 1;
2635 if (tree.tokenTag(maybe_comma) == .comma and space != .comma) {2631 if (tree.tokenTag(maybe_comma) == .comma and space != .comma) {
...@@ -2642,7 +2638,7 @@ fn renderTokenComma(r: *Render, token: Ast.TokenIndex, space: Space) Error!void...@@ -2642,7 +2638,7 @@ fn renderTokenComma(r: *Render, token: Ast.TokenIndex, space: Space) Error!void
26422638
2643/// Render an identifier, and the comma that follows it, if it is present in the source.2639/// Render an identifier, and the comma that follows it, if it is present in the source.
2644/// If a comma is present, and `space` is `Space.comma`, render only a single comma.2640/// If a comma is present, and `space` is `Space.comma`, render only a single comma.
2645fn renderIdentifierComma(r: *Render, token: Ast.TokenIndex, space: Space, quote: QuoteBehavior) Error!void {2641fn renderIdentifierComma(r: *Render, token: Ast.TokenIndex, space: Space, quote: QuoteBehavior) anyerror!void {
2646 const tree = r.tree;2642 const tree = r.tree;
2647 const maybe_comma = token + 1;2643 const maybe_comma = token + 1;
2648 if (tree.tokenTag(maybe_comma) == .comma and space != .comma) {2644 if (tree.tokenTag(maybe_comma) == .comma and space != .comma) {
...@@ -2674,15 +2670,15 @@ const Space = enum {...@@ -2674,15 +2670,15 @@ const Space = enum {
2674 skip,2670 skip,
2675};2671};
26762672
2677fn renderToken(r: *Render, token_index: Ast.TokenIndex, space: Space) Error!void {2673fn renderToken(r: *Render, token_index: Ast.TokenIndex, space: Space) anyerror!void {
2678 const tree = r.tree;2674 const tree = r.tree;
2679 const ais = r.ais;2675 const ais = r.ais;
2680 const lexeme = tokenSliceForRender(tree, token_index);2676 const lexeme = tokenSliceForRender(tree, token_index);
2681 try ais.writer().writeAll(lexeme);2677 try ais.writeAll(lexeme);
2682 try renderSpace(r, token_index, lexeme.len, space);2678 try renderSpace(r, token_index, lexeme.len, space);
2683}2679}
26842680
2685fn renderTokenOverrideSpaceMode(r: *Render, token_index: Ast.TokenIndex, space: Space, override_space: Space) Error!void {2681fn renderTokenOverrideSpaceMode(r: *Render, token_index: Ast.TokenIndex, space: Space, override_space: Space) anyerror!void {
2686 const tree = r.tree;2682 const tree = r.tree;
2687 const ais = r.ais;2683 const ais = r.ais;
2688 const lexeme = tokenSliceForRender(tree, token_index);2684 const lexeme = tokenSliceForRender(tree, token_index);
...@@ -2692,7 +2688,7 @@ fn renderTokenOverrideSpaceMode(r: *Render, token_index: Ast.TokenIndex, space:...@@ -2692,7 +2688,7 @@ fn renderTokenOverrideSpaceMode(r: *Render, token_index: Ast.TokenIndex, space:
2692 try renderSpace(r, token_index, lexeme.len, space);2688 try renderSpace(r, token_index, lexeme.len, space);
2693}2689}
26942690
2695fn renderSpace(r: *Render, token_index: Ast.TokenIndex, lexeme_len: usize, space: Space) Error!void {2691fn renderSpace(r: *Render, token_index: Ast.TokenIndex, lexeme_len: usize, space: Space) anyerror!void {
2696 const tree = r.tree;2692 const tree = r.tree;
2697 const ais = r.ais;2693 const ais = r.ais;
26982694
...@@ -2701,7 +2697,7 @@ fn renderSpace(r: *Render, token_index: Ast.TokenIndex, lexeme_len: usize, space...@@ -2701,7 +2697,7 @@ fn renderSpace(r: *Render, token_index: Ast.TokenIndex, lexeme_len: usize, space
2701 if (space == .skip) return;2697 if (space == .skip) return;
27022698
2703 if (space == .comma and next_token_tag != .comma) {2699 if (space == .comma and next_token_tag != .comma) {
2704 try ais.writer().writeByte(',');2700 try ais.underlying_writer.writeByte(',');
2705 }2701 }
2706 if (space == .semicolon or space == .comma) ais.enableSpaceMode(space);2702 if (space == .semicolon or space == .comma) ais.enableSpaceMode(space);
2707 defer ais.disableSpaceMode();2703 defer ais.disableSpaceMode();
...@@ -2712,7 +2708,7 @@ fn renderSpace(r: *Render, token_index: Ast.TokenIndex, lexeme_len: usize, space...@@ -2712,7 +2708,7 @@ fn renderSpace(r: *Render, token_index: Ast.TokenIndex, lexeme_len: usize, space
2712 );2708 );
2713 switch (space) {2709 switch (space) {
2714 .none => {},2710 .none => {},
2715 .space => if (!comment) try ais.writer().writeByte(' '),2711 .space => if (!comment) try ais.writeByte(' '),
2716 .newline => if (!comment) try ais.insertNewline(),2712 .newline => if (!comment) try ais.insertNewline(),
27172713
2718 .comma => if (next_token_tag == .comma) {2714 .comma => if (next_token_tag == .comma) {
...@@ -2724,7 +2720,7 @@ fn renderSpace(r: *Render, token_index: Ast.TokenIndex, lexeme_len: usize, space...@@ -2724,7 +2720,7 @@ fn renderSpace(r: *Render, token_index: Ast.TokenIndex, lexeme_len: usize, space
2724 .comma_space => if (next_token_tag == .comma) {2720 .comma_space => if (next_token_tag == .comma) {
2725 try renderToken(r, token_index + 1, .space);2721 try renderToken(r, token_index + 1, .space);
2726 } else if (!comment) {2722 } else if (!comment) {
2727 try ais.writer().writeByte(' ');2723 try ais.writeByte(' ');
2728 },2724 },
27292725
2730 .semicolon => if (next_token_tag == .semicolon) {2726 .semicolon => if (next_token_tag == .semicolon) {
...@@ -2737,15 +2733,15 @@ fn renderSpace(r: *Render, token_index: Ast.TokenIndex, lexeme_len: usize, space...@@ -2737,15 +2733,15 @@ fn renderSpace(r: *Render, token_index: Ast.TokenIndex, lexeme_len: usize, space
2737 }2733 }
2738}2734}
27392735
2740fn renderOnlySpace(r: *Render, space: Space) Error!void {2736fn renderOnlySpace(r: *Render, space: Space) anyerror!void {
2741 const ais = r.ais;2737 const ais = r.ais;
2742 switch (space) {2738 switch (space) {
2743 .none => {},2739 .none => {},
2744 .space => try ais.writer().writeByte(' '),2740 .space => try ais.writeByte(' '),
2745 .newline => try ais.insertNewline(),2741 .newline => try ais.insertNewline(),
2746 .comma => try ais.writer().writeAll(",\n"),2742 .comma => try ais.writeAll(",\n"),
2747 .comma_space => try ais.writer().writeAll(", "),2743 .comma_space => try ais.writeAll(", "),
2748 .semicolon => try ais.writer().writeAll(";\n"),2744 .semicolon => try ais.writeAll(";\n"),
2749 .skip => unreachable,2745 .skip => unreachable,
2750 }2746 }
2751}2747}
...@@ -2756,13 +2752,13 @@ const QuoteBehavior = enum {...@@ -2756,13 +2752,13 @@ const QuoteBehavior = enum {
2756 eagerly_unquote_except_underscore,2752 eagerly_unquote_except_underscore,
2757};2753};
27582754
2759fn renderIdentifier(r: *Render, token_index: Ast.TokenIndex, space: Space, quote: QuoteBehavior) Error!void {2755fn renderIdentifier(r: *Render, token_index: Ast.TokenIndex, space: Space, quote: QuoteBehavior) anyerror!void {
2760 const tree = r.tree;2756 const tree = r.tree;
2761 assert(tree.tokenTag(token_index) == .identifier);2757 assert(tree.tokenTag(token_index) == .identifier);
2762 const lexeme = tokenSliceForRender(tree, token_index);2758 const lexeme = tokenSliceForRender(tree, token_index);
27632759
2764 if (r.fixups.rename_identifiers.get(lexeme)) |mangled| {2760 if (r.fixups.rename_identifiers.get(lexeme)) |mangled| {
2765 try r.ais.writer().writeAll(mangled);2761 try r.ais.writeAll(mangled);
2766 try renderSpace(r, token_index, lexeme.len, space);2762 try renderSpace(r, token_index, lexeme.len, space);
2767 return;2763 return;
2768 }2764 }
...@@ -2871,15 +2867,15 @@ fn renderQuotedIdentifier(r: *Render, token_index: Ast.TokenIndex, space: Space,...@@ -2871,15 +2867,15 @@ fn renderQuotedIdentifier(r: *Render, token_index: Ast.TokenIndex, space: Space,
2871 const lexeme = tokenSliceForRender(tree, token_index);2867 const lexeme = tokenSliceForRender(tree, token_index);
2872 assert(lexeme.len >= 3 and lexeme[0] == '@');2868 assert(lexeme.len >= 3 and lexeme[0] == '@');
28732869
2874 if (!unquote) try ais.writer().writeAll("@\"");2870 if (!unquote) try ais.writeAll("@\"");
2875 const contents = lexeme[2 .. lexeme.len - 1];2871 const contents = lexeme[2 .. lexeme.len - 1];
2876 try renderIdentifierContents(ais.writer(), contents);2872 try renderIdentifierContents(ais, contents);
2877 if (!unquote) try ais.writer().writeByte('\"');2873 if (!unquote) try ais.writeByte('\"');
28782874
2879 try renderSpace(r, token_index, lexeme.len, space);2875 try renderSpace(r, token_index, lexeme.len, space);
2880}2876}
28812877
2882fn renderIdentifierContents(writer: anytype, bytes: []const u8) !void {2878fn renderIdentifierContents(ais: *AutoIndentingStream, bytes: []const u8) !void {
2883 var pos: usize = 0;2879 var pos: usize = 0;
2884 while (pos < bytes.len) {2880 while (pos < bytes.len) {
2885 const byte = bytes[pos];2881 const byte = bytes[pos];
...@@ -2892,23 +2888,23 @@ fn renderIdentifierContents(writer: anytype, bytes: []const u8) !void {...@@ -2892,23 +2888,23 @@ fn renderIdentifierContents(writer: anytype, bytes: []const u8) !void {
2892 .success => |codepoint| {2888 .success => |codepoint| {
2893 if (codepoint <= 0x7f) {2889 if (codepoint <= 0x7f) {
2894 const buf = [1]u8{@as(u8, @intCast(codepoint))};2890 const buf = [1]u8{@as(u8, @intCast(codepoint))};
2895 try std.fmt.format(writer, "{}", .{std.zig.fmtEscapes(&buf)});2891 try ais.print("{}", .{std.zig.fmtEscapes(&buf)});
2896 } else {2892 } else {
2897 try writer.writeAll(escape_sequence);2893 try ais.writeAll(escape_sequence);
2898 }2894 }
2899 },2895 },
2900 .failure => {2896 .failure => {
2901 try writer.writeAll(escape_sequence);2897 try ais.writeAll(escape_sequence);
2902 },2898 },
2903 }2899 }
2904 },2900 },
2905 0x00...('\\' - 1), ('\\' + 1)...0x7f => {2901 0x00...('\\' - 1), ('\\' + 1)...0x7f => {
2906 const buf = [1]u8{byte};2902 const buf = [1]u8{byte};
2907 try std.fmt.format(writer, "{}", .{std.zig.fmtEscapes(&buf)});2903 try ais.print("{}", .{std.zig.fmtEscapes(&buf)});
2908 pos += 1;2904 pos += 1;
2909 },2905 },
2910 0x80...0xff => {2906 0x80...0xff => {
2911 try writer.writeByte(byte);2907 try ais.writeByte(byte);
2912 pos += 1;2908 pos += 1;
2913 },2909 },
2914 }2910 }
...@@ -2942,7 +2938,7 @@ fn hasMultilineString(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.Tok...@@ -2942,7 +2938,7 @@ fn hasMultilineString(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.Tok
29422938
2943/// Assumes that start is the first byte past the previous token and2939/// Assumes that start is the first byte past the previous token and
2944/// that end is the last byte before the next token.2940/// that end is the last byte before the next token.
2945fn renderComments(r: *Render, start: usize, end: usize) Error!bool {2941fn renderComments(r: *Render, start: usize, end: usize) anyerror!bool {
2946 const tree = r.tree;2942 const tree = r.tree;
2947 const ais = r.ais;2943 const ais = r.ais;
29482944
...@@ -2970,7 +2966,7 @@ fn renderComments(r: *Render, start: usize, end: usize) Error!bool {...@@ -2970,7 +2966,7 @@ fn renderComments(r: *Render, start: usize, end: usize) Error!bool {
2970 } else if (index == start) {2966 } else if (index == start) {
2971 // Otherwise if the first comment is on the same line as2967 // Otherwise if the first comment is on the same line as
2972 // the token before it, prefix it with a single space.2968 // the token before it, prefix it with a single space.
2973 try ais.writer().writeByte(' ');2969 try ais.writeByte(' ');
2974 }2970 }
2975 }2971 }
29762972
...@@ -2987,11 +2983,11 @@ fn renderComments(r: *Render, start: usize, end: usize) Error!bool {...@@ -2987,11 +2983,11 @@ fn renderComments(r: *Render, start: usize, end: usize) Error!bool {
2987 ais.disabled_offset = null;2983 ais.disabled_offset = null;
2988 } else if (ais.disabled_offset == null and mem.eql(u8, comment_content, "zig fmt: off")) {2984 } else if (ais.disabled_offset == null and mem.eql(u8, comment_content, "zig fmt: off")) {
2989 // Write with the canonical single space.2985 // Write with the canonical single space.
2990 try ais.writer().writeAll("// zig fmt: off\n");2986 try ais.writeAll("// zig fmt: off\n");
2991 ais.disabled_offset = index;2987 ais.disabled_offset = index;
2992 } else {2988 } else {
2993 // Write the comment minus trailing whitespace.2989 // Write the comment minus trailing whitespace.
2994 try ais.writer().print("{s}\n", .{trimmed_comment});2990 try ais.print("{s}\n", .{trimmed_comment});
2995 }2991 }
2996 }2992 }
29972993
...@@ -3005,12 +3001,12 @@ fn renderComments(r: *Render, start: usize, end: usize) Error!bool {...@@ -3005,12 +3001,12 @@ fn renderComments(r: *Render, start: usize, end: usize) Error!bool {
3005 return index != start;3001 return index != start;
3006}3002}
30073003
3008fn renderExtraNewline(r: *Render, node: Ast.Node.Index) Error!void {3004fn renderExtraNewline(r: *Render, node: Ast.Node.Index) anyerror!void {
3009 return renderExtraNewlineToken(r, r.tree.firstToken(node));3005 return renderExtraNewlineToken(r, r.tree.firstToken(node));
3010}3006}
30113007
3012/// Check if there is an empty line immediately before the given token. If so, render it.3008/// Check if there is an empty line immediately before the given token. If so, render it.
3013fn renderExtraNewlineToken(r: *Render, token_index: Ast.TokenIndex) Error!void {3009fn renderExtraNewlineToken(r: *Render, token_index: Ast.TokenIndex) anyerror!void {
3014 const tree = r.tree;3010 const tree = r.tree;
3015 const ais = r.ais;3011 const ais = r.ais;
3016 const token_start = tree.tokenStart(token_index);3012 const token_start = tree.tokenStart(token_index);
...@@ -3038,7 +3034,7 @@ fn renderExtraNewlineToken(r: *Render, token_index: Ast.TokenIndex) Error!void {...@@ -3038,7 +3034,7 @@ fn renderExtraNewlineToken(r: *Render, token_index: Ast.TokenIndex) Error!void {
30383034
3039/// end_token is the token one past the last doc comment token. This function3035/// end_token is the token one past the last doc comment token. This function
3040/// searches backwards from there.3036/// searches backwards from there.
3041fn renderDocComments(r: *Render, end_token: Ast.TokenIndex) Error!void {3037fn renderDocComments(r: *Render, end_token: Ast.TokenIndex) anyerror!void {
3042 const tree = r.tree;3038 const tree = r.tree;
3043 // Search backwards for the first doc comment.3039 // Search backwards for the first doc comment.
3044 if (end_token == 0) return;3040 if (end_token == 0) return;
...@@ -3069,7 +3065,7 @@ fn renderDocComments(r: *Render, end_token: Ast.TokenIndex) Error!void {...@@ -3069,7 +3065,7 @@ fn renderDocComments(r: *Render, end_token: Ast.TokenIndex) Error!void {
3069}3065}
30703066
3071/// start_token is first container doc comment token.3067/// start_token is first container doc comment token.
3072fn renderContainerDocComments(r: *Render, start_token: Ast.TokenIndex) Error!void {3068fn renderContainerDocComments(r: *Render, start_token: Ast.TokenIndex) anyerror!void {
3073 const tree = r.tree;3069 const tree = r.tree;
3074 var tok = start_token;3070 var tok = start_token;
3075 while (tree.tokenTag(tok) == .container_doc_comment) : (tok += 1) {3071 while (tree.tokenTag(tok) == .container_doc_comment) : (tok += 1) {
...@@ -3083,7 +3079,7 @@ fn renderContainerDocComments(r: *Render, start_token: Ast.TokenIndex) Error!voi...@@ -3083,7 +3079,7 @@ fn renderContainerDocComments(r: *Render, start_token: Ast.TokenIndex) Error!voi
3083 }3079 }
3084}3080}
30853081
3086fn discardAllParams(r: *Render, fn_proto_node: Ast.Node.Index) Error!void {3082fn discardAllParams(r: *Render, fn_proto_node: Ast.Node.Index) anyerror!void {
3087 const tree = &r.tree;3083 const tree = &r.tree;
3088 const ais = r.ais;3084 const ais = r.ais;
3089 var buf: [1]Ast.Node.Index = undefined;3085 var buf: [1]Ast.Node.Index = undefined;
...@@ -3092,10 +3088,9 @@ fn discardAllParams(r: *Render, fn_proto_node: Ast.Node.Index) Error!void {...@@ -3092,10 +3088,9 @@ fn discardAllParams(r: *Render, fn_proto_node: Ast.Node.Index) Error!void {
3092 while (it.next()) |param| {3088 while (it.next()) |param| {
3093 const name_ident = param.name_token.?;3089 const name_ident = param.name_token.?;
3094 assert(tree.tokenTag(name_ident) == .identifier);3090 assert(tree.tokenTag(name_ident) == .identifier);
3095 const w = ais.writer();3091 try ais.writeAll("_ = ");
3096 try w.writeAll("_ = ");3092 try ais.writeAll(tokenSliceForRender(r.tree, name_ident));
3097 try w.writeAll(tokenSliceForRender(r.tree, name_ident));3093 try ais.writeAll(";\n");
3098 try w.writeAll(";\n");
3099 }3094 }
3100}3095}
31013096
...@@ -3132,11 +3127,11 @@ fn anythingBetween(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenI...@@ -3132,11 +3127,11 @@ fn anythingBetween(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenI
3132 return false;3127 return false;
3133}3128}
31343129
3135fn writeFixingWhitespace(writer: std.ArrayList(u8).Writer, slice: []const u8) Error!void {3130fn writeFixingWhitespace(bw: *std.io.BufferedWriter, slice: []const u8) anyerror!void {
3136 for (slice) |byte| switch (byte) {3131 for (slice) |byte| switch (byte) {
3137 '\t' => try writer.writeAll(" " ** indent_delta),3132 '\t' => try bw.splatByteAll(' ', indent_delta),
3138 '\r' => {},3133 '\r' => {},
3139 else => try writer.writeByte(byte),3134 else => try bw.writeByte(byte),
3140 };3135 };
3141}3136}
31423137
...@@ -3261,224 +3256,235 @@ fn rowSize(tree: Ast, exprs: []const Ast.Node.Index, rtoken: Ast.TokenIndex) usi...@@ -3261,224 +3256,235 @@ fn rowSize(tree: Ast, exprs: []const Ast.Node.Index, rtoken: Ast.TokenIndex) usi
3261/// of the appropriate indentation level for them with pushSpace/popSpace.3256/// of the appropriate indentation level for them with pushSpace/popSpace.
3262/// This should be done whenever a scope that ends in a .semicolon or a3257/// This should be done whenever a scope that ends in a .semicolon or a
3263/// .comma is introduced.3258/// .comma is introduced.
3264fn AutoIndentingStream(comptime UnderlyingWriter: type) type {3259const AutoIndentingStream = struct {
3265 return struct {3260 underlying_writer: *std.io.BufferedWriter,
3266 const Self = @This();3261
3267 pub const WriteError = UnderlyingWriter.Error;3262 indent_count: usize = 0,
3268 pub const Writer = std.io.Writer(*Self, WriteError, write);3263 indent_delta: usize,
32693264 indent_stack: std.ArrayList(StackElem),
3270 pub const IndentType = enum {3265 space_stack: std.ArrayList(SpaceElem),
3271 normal,3266 space_mode: ?usize = null,
3272 after_equals,3267 disable_indent_committing: usize = 0,
3273 binop,3268 current_line_empty: bool = true,
3274 field_access,3269 /// the most recently applied indent
3275 };3270 applied_indent: usize = 0,
3276 const StackElem = struct {3271
3277 indent_type: IndentType,3272 pub const IndentType = enum {
3278 realized: bool,3273 normal,
3279 };3274 after_equals,
3280 const SpaceElem = struct {3275 binop,
3281 space: Space,3276 field_access,
3282 indent_count: usize,3277 };
3278 const StackElem = struct {
3279 indent_type: IndentType,
3280 realized: bool,
3281 };
3282 const SpaceElem = struct {
3283 space: Space,
3284 indent_count: usize,
3285 };
3286
3287 pub fn init(buffer: *std.ArrayList(u8), indent_delta_: usize) AutoIndentingStream {
3288 return .{
3289 .underlying_writer = buffer.writer(),
3290 .indent_delta = indent_delta_,
3291 .indent_stack = std.ArrayList(StackElem).init(buffer.allocator),
3292 .space_stack = std.ArrayList(SpaceElem).init(buffer.allocator),
3283 };3293 };
3294 }
32843295
3285 underlying_writer: UnderlyingWriter,3296 pub fn deinit(self: *AutoIndentingStream) void {
32863297 self.indent_stack.deinit();
3287 /// Offset into the source at which formatting has been disabled with3298 self.space_stack.deinit();
3288 /// a `zig fmt: off` comment.3299 }
3289 ///
3290 /// If non-null, the AutoIndentingStream will not write any bytes
3291 /// to the underlying writer. It will however continue to track the
3292 /// indentation level.
3293 disabled_offset: ?usize = null,
3294
3295 indent_count: usize = 0,
3296 indent_delta: usize,
3297 indent_stack: std.ArrayList(StackElem),
3298 space_stack: std.ArrayList(SpaceElem),
3299 space_mode: ?usize = null,
3300 disable_indent_committing: usize = 0,
3301 current_line_empty: bool = true,
3302 /// the most recently applied indent
3303 applied_indent: usize = 0,
3304
3305 pub fn init(buffer: *std.ArrayList(u8), indent_delta_: usize) Self {
3306 return .{
3307 .underlying_writer = buffer.writer(),
3308 .indent_delta = indent_delta_,
3309 .indent_stack = std.ArrayList(StackElem).init(buffer.allocator),
3310 .space_stack = std.ArrayList(SpaceElem).init(buffer.allocator),
3311 };
3312 }
33133300
3314 pub fn deinit(self: *Self) void {3301 pub fn writeAll(ais: *AutoIndentingStream, bytes: []const u8) anyerror!void {
3315 self.indent_stack.deinit();3302 if (bytes.len == 0) return;
3316 self.space_stack.deinit();3303 try ais.applyIndent();
3317 }3304 if (ais.disabled_offset == null) try ais.underlying_writer.writeAll(bytes);
3305 if (bytes[bytes.len - 1] == '\n') ais.resetLine();
3306 }
33183307
3319 pub fn writer(self: *Self) Writer {3308 pub fn print(ais: *AutoIndentingStream, comptime format: []const u8, args: anytype) anyerror!void {
3320 return .{ .context = self };3309 comptime assert(format[format.len - 1] != '}');
3321 }3310 try ais.applyIndent();
3311 if (ais.disabled_offset == null) try ais.underlying_writer.print(format, args);
3312 if (format[format.len - 1] == '\n') ais.resetLine();
3313 }
33223314
3323 pub fn write(self: *Self, bytes: []const u8) WriteError!usize {3315 pub fn writeByte(ais: *AutoIndentingStream, byte: u8) anyerror!void {
3324 if (bytes.len == 0)3316 try ais.applyIndent();
3325 return @as(usize, 0);3317 if (ais.disabled_offset == null) try ais.underlying_writer.writeByte(byte);
3318 assert(byte != '\n');
3319 }
33263320
3327 try self.applyIndent();3321 pub fn splatByteAll(ais: *AutoIndentingStream, byte: u8, n: usize) anyerror!void {
3328 return self.writeNoIndent(bytes);3322 assert(byte != '\n');
3329 }3323 try ais.applyIndent();
3324 if (ais.disabled_offset == null) try ais.underlying_writer.splatByteAll(byte, n);
3325 }
33303326
3331 // Change the indent delta without changing the final indentation level3327 // Change the indent delta without changing the final indentation level
3332 pub fn setIndentDelta(self: *Self, new_indent_delta: usize) void {3328 pub fn setIndentDelta(ais: *AutoIndentingStream, new_indent_delta: usize) void {
3333 if (self.indent_delta == new_indent_delta) {3329 if (ais.indent_delta == new_indent_delta) {
3334 return;3330 return;
3335 } else if (self.indent_delta > new_indent_delta) {3331 } else if (ais.indent_delta > new_indent_delta) {
3336 assert(self.indent_delta % new_indent_delta == 0);3332 assert(ais.indent_delta % new_indent_delta == 0);
3337 self.indent_count = self.indent_count * (self.indent_delta / new_indent_delta);3333 ais.indent_count = ais.indent_count * (ais.indent_delta / new_indent_delta);
3338 } else {3334 } else {
3339 // assert that the current indentation (in spaces) in a multiple of the new delta3335 // assert that the current indentation (in spaces) in a multiple of the new delta
3340 assert((self.indent_count * self.indent_delta) % new_indent_delta == 0);3336 assert((ais.indent_count * ais.indent_delta) % new_indent_delta == 0);
3341 self.indent_count = self.indent_count / (new_indent_delta / self.indent_delta);3337 ais.indent_count = ais.indent_count / (new_indent_delta / ais.indent_delta);
3342 }
3343 self.indent_delta = new_indent_delta;
3344 }3338 }
3339 ais.indent_delta = new_indent_delta;
3340 }
33453341
3346 fn writeNoIndent(self: *Self, bytes: []const u8) WriteError!usize {3342 pub fn insertNewline(ais: *AutoIndentingStream) anyerror!void {
3347 if (bytes.len == 0)3343 if (ais.disabled_offset == null) try ais.underlying_writer.writeByte('\n');
3348 return @as(usize, 0);3344 ais.resetLine();
3345 }
33493346
3350 if (self.disabled_offset == null) try self.underlying_writer.writeAll(bytes);3347 /// Insert a newline unless the current line is blank
3351 if (bytes[bytes.len - 1] == '\n')3348 pub fn maybeInsertNewline(ais: *AutoIndentingStream) anyerror!void {
3352 self.resetLine();3349 if (!ais.current_line_empty)
3353 return bytes.len;3350 try ais.insertNewline();
3354 }3351 }
33553352
3356 pub fn insertNewline(self: *Self) WriteError!void {3353 /// Push an indent that is automatically popped after being applied
3357 _ = try self.writeNoIndent("\n");3354 pub fn pushIndentOneShot(ais: *AutoIndentingStream) void {
3358 }3355 ais.indent_one_shot_count += 1;
3356 ais.pushIndent();
3357 }
33593358
3360 fn resetLine(self: *Self) void {3359 /// Turns all one-shot indents into regular indents
3361 self.current_line_empty = true;3360 /// Returns number of indents that must now be manually popped
33623361 pub fn lockOneShotIndent(ais: *AutoIndentingStream) usize {
3363 if (self.disable_indent_committing > 0) return;3362 const locked_count = ais.indent_one_shot_count;
33643363 ais.indent_one_shot_count = 0;
3365 if (self.indent_stack.items.len > 0) {3364 return locked_count;
3366 // By default, we realize the most recent indentation scope.3365 }
3367 var to_realize = self.indent_stack.items.len - 1;
3368
3369 if (self.indent_stack.items.len >= 2 and
3370 self.indent_stack.items[to_realize - 1].indent_type == .after_equals and
3371 self.indent_stack.items[to_realize - 1].realized and
3372 self.indent_stack.items[to_realize].indent_type == .binop)
3373 {
3374 // If we are in a .binop scope and our direct parent is .after_equals, don't indent.
3375 // This ensures correct indentation in the below example:
3376 //
3377 // const foo =
3378 // (x >= 'a' and x <= 'z') or //<-- we are here
3379 // (x >= 'A' and x <= 'Z');
3380 //
3381 return;
3382 }
33833366
3384 if (self.indent_stack.items[to_realize].indent_type == .field_access) {3367 /// Push an indent that should not take effect until the next line
3385 // Only realize the top-most field_access in a chain.3368 pub fn pushIndentNextLine(ais: *AutoIndentingStream) void {
3386 while (to_realize > 0 and self.indent_stack.items[to_realize - 1].indent_type == .field_access)3369 ais.indent_next_line += 1;
3387 to_realize -= 1;3370 ais.pushIndent();
3388 }3371 }
3372
3373 /// Checks to see if the most recent indentation exceeds the currently pushed indents
3374 pub fn isLineOverIndented(ais: *AutoIndentingStream) bool {
3375 if (ais.current_line_empty) return false;
3376 return ais.applied_indent > ais.currentIndent();
3377 }
3378
3379 fn resetLine(ais: *AutoIndentingStream) void {
3380 ais.current_line_empty = true;
3381
3382 if (ais.disable_indent_committing > 0) return;
33893383
3390 if (self.indent_stack.items[to_realize].realized) return;3384 if (ais.indent_stack.items.len > 0) {
3391 self.indent_stack.items[to_realize].realized = true;3385 // By default, we realize the most recent indentation scope.
3392 self.indent_count += 1;3386 var to_realize = ais.indent_stack.items.len - 1;
3387
3388 if (ais.indent_stack.items.len >= 2 and
3389 ais.indent_stack.items[to_realize - 1].indent_type == .after_equals and
3390 ais.indent_stack.items[to_realize - 1].realized and
3391 ais.indent_stack.items[to_realize].indent_type == .binop)
3392 {
3393 // If we are in a .binop scope and our direct parent is .after_equals, don't indent.
3394 // This ensures correct indentation in the below example:
3395 //
3396 // const foo =
3397 // (x >= 'a' and x <= 'z') or //<-- we are here
3398 // (x >= 'A' and x <= 'Z');
3399 //
3400 return;
3393 }3401 }
3394 }
33953402
3396 /// Disables indentation level changes during the next newlines until re-enabled.3403 if (ais.indent_stack.items[to_realize].indent_type == .field_access) {
3397 pub fn disableIndentCommitting(self: *Self) void {3404 // Only realize the top-most field_access in a chain.
3398 self.disable_indent_committing += 1;3405 while (to_realize > 0 and ais.indent_stack.items[to_realize - 1].indent_type == .field_access)
3399 }3406 to_realize -= 1;
3407 }
34003408
3401 pub fn enableIndentCommitting(self: *Self) void {3409 if (ais.indent_stack.items[to_realize].realized) return;
3402 assert(self.disable_indent_committing > 0);3410 ais.indent_stack.items[to_realize].realized = true;
3403 self.disable_indent_committing -= 1;3411 ais.indent_count += 1;
3404 }3412 }
3413 }
34053414
3406 pub fn pushSpace(self: *Self, space: Space) !void {3415 /// Disables indentation level changes during the next newlines until re-enabled.
3407 try self.space_stack.append(.{ .space = space, .indent_count = self.indent_count });3416 pub fn disableIndentCommitting(ais: *AutoIndentingStream) void {
3408 }3417 ais.disable_indent_committing += 1;
3418 }
34093419
3410 pub fn popSpace(self: *Self) void {3420 pub fn enableIndentCommitting(ais: *AutoIndentingStream) void {
3411 _ = self.space_stack.pop();3421 assert(ais.disable_indent_committing > 0);
3412 }3422 ais.disable_indent_committing -= 1;
3423 }
34133424
3414 /// Sets current indentation level to be the same as that of the last pushSpace.3425 pub fn pushSpace(ais: *AutoIndentingStream, space: Space) !void {
3415 pub fn enableSpaceMode(self: *Self, space: Space) void {3426 try ais.space_stack.append(.{ .space = space, .indent_count = ais.indent_count });
3416 if (self.space_stack.items.len == 0) return;3427 }
3417 const curr = self.space_stack.getLast();
3418 if (curr.space != space) return;
3419 self.space_mode = curr.indent_count;
3420 }
34213428
3422 pub fn disableSpaceMode(self: *Self) void {3429 pub fn popSpace(ais: *AutoIndentingStream) void {
3423 self.space_mode = null;3430 _ = ais.space_stack.pop();
3424 }3431 }
34253432
3426 pub fn lastSpaceModeIndent(self: *Self) usize {3433 /// Sets current indentation level to be the same as that of the last pushSpace.
3427 if (self.space_stack.items.len == 0) return 0;3434 pub fn enableSpaceMode(ais: *AutoIndentingStream, space: Space) void {
3428 return self.space_stack.getLast().indent_count * self.indent_delta;3435 if (ais.space_stack.items.len == 0) return;
3429 }3436 const curr = ais.space_stack.getLast();
3437 if (curr.space != space) return;
3438 ais.space_mode = curr.indent_count;
3439 }
34303440
3431 /// Insert a newline unless the current line is blank3441 pub fn disableSpaceMode(ais: *AutoIndentingStream) void {
3432 pub fn maybeInsertNewline(self: *Self) WriteError!void {3442 ais.space_mode = null;
3433 if (!self.current_line_empty)3443 }
3434 try self.insertNewline();
3435 }
34363444
3437 /// Push default indentation3445 pub fn lastSpaceModeIndent(ais: *AutoIndentingStream) usize {
3438 /// Doesn't actually write any indentation.3446 if (ais.space_stack.items.len == 0) return 0;
3439 /// Just primes the stream to be able to write the correct indentation if it needs to.3447 return ais.space_stack.getLast().indent_count * ais.indent_delta;
3440 pub fn pushIndent(self: *Self, indent_type: IndentType) !void {3448 }
3441 try self.indent_stack.append(.{ .indent_type = indent_type, .realized = false });
3442 }
34433449
3444 /// Forces an indentation level to be realized.3450 /// Push default indentation
3445 pub fn forcePushIndent(self: *Self, indent_type: IndentType) !void {3451 /// Doesn't actually write any indentation.
3446 try self.indent_stack.append(.{ .indent_type = indent_type, .realized = true });3452 /// Just primes the stream to be able to write the correct indentation if it needs to.
3447 self.indent_count += 1;3453 pub fn pushIndent(ais: *AutoIndentingStream, indent_type: IndentType) !void {
3448 }3454 try ais.indent_stack.append(.{ .indent_type = indent_type, .realized = false });
3455 }
34493456
3450 pub fn popIndent(self: *Self) void {3457 /// Forces an indentation level to be realized.
3451 if (self.indent_stack.pop().?.realized) {3458 pub fn forcePushIndent(ais: *AutoIndentingStream, indent_type: IndentType) !void {
3452 assert(self.indent_count > 0);3459 try ais.indent_stack.append(.{ .indent_type = indent_type, .realized = true });
3453 self.indent_count -= 1;3460 ais.indent_count += 1;
3454 }3461 }
3455 }
34563462
3457 pub fn indentStackEmpty(self: *Self) bool {3463 pub fn popIndent(ais: *AutoIndentingStream) void {
3458 return self.indent_stack.items.len == 0;3464 if (ais.indent_stack.pop().?.realized) {
3465 assert(ais.indent_count > 0);
3466 ais.indent_count -= 1;
3459 }3467 }
3468 }
34603469
3461 /// Writes ' ' bytes if the current line is empty3470 pub fn indentStackEmpty(ais: *AutoIndentingStream) bool {
3462 fn applyIndent(self: *Self) WriteError!void {3471 return ais.indent_stack.items.len == 0;
3463 const current_indent = self.currentIndent();3472 }
3464 if (self.current_line_empty and current_indent > 0) {
3465 if (self.disabled_offset == null) {
3466 try self.underlying_writer.writeByteNTimes(' ', current_indent);
3467 }
3468 self.applied_indent = current_indent;
3469 }
3470 self.current_line_empty = false;
3471 }
34723473
3473 /// Checks to see if the most recent indentation exceeds the currently pushed indents3474 /// Writes ' ' bytes if the current line is empty
3474 pub fn isLineOverIndented(self: *Self) bool {3475 fn applyIndent(ais: *AutoIndentingStream) anyerror!void {
3475 if (self.current_line_empty) return false;3476 const current_indent = ais.currentIndent();
3476 return self.applied_indent > self.currentIndent();3477 if (ais.current_line_empty and current_indent > 0) {
3478 if (ais.disabled_offset == null) {
3479 try ais.underlying_writer.writeByteNTimes(' ', current_indent);
3480 }
3481 ais.applied_indent = current_indent;
3477 }3482 }
3483 ais.current_line_empty = false;
3484 }
34783485
3479 fn currentIndent(self: *Self) usize {3486 fn currentIndent(ais: *AutoIndentingStream) usize {
3480 const indent_count = self.space_mode orelse self.indent_count;3487 const indent_count = ais.space_mode orelse ais.indent_count;
3481 return indent_count * self.indent_delta;3488 return indent_count * ais.indent_delta;
3482 }3489 }
3483 };3490};
3484}
lib/std/zig/string_literal.zig+11-9
...@@ -322,9 +322,9 @@ test parseCharLiteral {...@@ -322,9 +322,9 @@ test parseCharLiteral {
322 );322 );
323}323}
324324
325/// Parses `bytes` as a Zig string literal and writes the result to the std.io.Writer type.325/// Parses `bytes` as a Zig string literal and writes the result to the `std.io.Writer` type.
326/// Asserts `bytes` has '"' at beginning and end.326/// Asserts `bytes` has '"' at beginning and end.
327pub fn parseWrite(writer: anytype, bytes: []const u8) error{OutOfMemory}!Result {327pub fn parseWrite(writer: *std.io.BufferedWriter, bytes: []const u8) anyerror!Result {
328 assert(bytes.len >= 2 and bytes[0] == '"' and bytes[bytes.len - 1] == '"');328 assert(bytes.len >= 2 and bytes[0] == '"' and bytes[bytes.len - 1] == '"');
329329
330 var index: usize = 1;330 var index: usize = 1;
...@@ -340,18 +340,18 @@ pub fn parseWrite(writer: anytype, bytes: []const u8) error{OutOfMemory}!Result...@@ -340,18 +340,18 @@ pub fn parseWrite(writer: anytype, bytes: []const u8) error{OutOfMemory}!Result
340 if (bytes[escape_char_index] == 'u') {340 if (bytes[escape_char_index] == 'u') {
341 var buf: [4]u8 = undefined;341 var buf: [4]u8 = undefined;
342 const len = utf8Encode(codepoint, &buf) catch {342 const len = utf8Encode(codepoint, &buf) catch {
343 return Result{ .failure = .{ .invalid_unicode_codepoint = escape_char_index + 1 } };343 return .{ .failure = .{ .invalid_unicode_codepoint = escape_char_index + 1 } };
344 };344 };
345 try writer.writeAll(buf[0..len]);345 try writer.writeAll(buf[0..len]);
346 } else {346 } else {
347 try writer.writeByte(@as(u8, @intCast(codepoint)));347 try writer.writeByte(@as(u8, @intCast(codepoint)));
348 }348 }
349 },349 },
350 .failure => |err| return Result{ .failure = err },350 .failure => |err| return .{ .failure = err },
351 }351 }
352 },352 },
353 '\n' => return Result{ .failure = .{ .invalid_character = index } },353 '\n' => return .{ .failure = .{ .invalid_character = index } },
354 '"' => return Result.success,354 '"' => return .success,
355 else => {355 else => {
356 try writer.writeByte(b);356 try writer.writeByte(b);
357 index += 1;357 index += 1;
...@@ -363,10 +363,12 @@ pub fn parseWrite(writer: anytype, bytes: []const u8) error{OutOfMemory}!Result...@@ -363,10 +363,12 @@ pub fn parseWrite(writer: anytype, bytes: []const u8) error{OutOfMemory}!Result
363/// Higher level API. Does not return extra info about parse errors.363/// Higher level API. Does not return extra info about parse errors.
364/// Caller owns returned memory.364/// Caller owns returned memory.
365pub fn parseAlloc(allocator: std.mem.Allocator, bytes: []const u8) ParseError![]u8 {365pub fn parseAlloc(allocator: std.mem.Allocator, bytes: []const u8) ParseError![]u8 {
366 var buf = std.ArrayList(u8).init(allocator);366 var buf: std.io.AllocatingWriter = undefined;
367 const bw = buf.init(allocator);
367 defer buf.deinit();368 defer buf.deinit();
368369 // TODO try @errorCast(...)
369 switch (try parseWrite(buf.writer(), bytes)) {370 const result = parseWrite(bw, bytes) catch |err| return @errorCast(err);
371 switch (result) {
370 .success => return buf.toOwnedSlice(),372 .success => return buf.toOwnedSlice(),
371 .failure => return error.InvalidLiteral,373 .failure => return error.InvalidLiteral,
372 }374 }
src/Air/print.zig+12-13
...@@ -1,6 +1,5 @@...@@ -1,6 +1,5 @@
1const std = @import("std");1const std = @import("std");
2const Allocator = std.mem.Allocator;2const Allocator = std.mem.Allocator;
3const fmtIntSizeBin = std.fmt.fmtIntSizeBin;
43
5const build_options = @import("build_options");4const build_options = @import("build_options");
6const Zcu = @import("../Zcu.zig");5const Zcu = @import("../Zcu.zig");
...@@ -25,20 +24,20 @@ pub fn write(air: Air, stream: anytype, pt: Zcu.PerThread, liveness: ?Air.Livene...@@ -25,20 +24,20 @@ pub fn write(air: Air, stream: anytype, pt: Zcu.PerThread, liveness: ?Air.Livene
2524
26 // zig fmt: off25 // zig fmt: off
27 stream.print(26 stream.print(
28 \\# Total AIR+Liveness bytes: {}27 \\# Total AIR+Liveness bytes: {Bi}
29 \\# AIR Instructions: {d} ({})28 \\# AIR Instructions: {d} ({Bi})
30 \\# AIR Extra Data: {d} ({})29 \\# AIR Extra Data: {d} ({Bi})
31 \\# Liveness tomb_bits: {}30 \\# Liveness tomb_bits: {Bi}
32 \\# Liveness Extra Data: {d} ({})31 \\# Liveness Extra Data: {d} ({Bi})
33 \\# Liveness special table: {d} ({})32 \\# Liveness special table: {d} ({Bi})
34 \\33 \\
35 , .{34 , .{
36 fmtIntSizeBin(total_bytes),35 total_bytes,
37 air.instructions.len, fmtIntSizeBin(instruction_bytes),36 air.instructions.len, instruction_bytes,
38 air.extra.items.len, fmtIntSizeBin(extra_bytes),37 air.extra.items.len, extra_bytes,
39 fmtIntSizeBin(tomb_bytes),38 tomb_bytes,
40 if (liveness) |l| l.extra.len else 0, fmtIntSizeBin(liveness_extra_bytes),39 if (liveness) |l| l.extra.len else 0, liveness_extra_bytes,
41 if (liveness) |l| l.special.count() else 0, fmtIntSizeBin(liveness_special_bytes),40 if (liveness) |l| l.special.count() else 0, liveness_special_bytes,
42 }) catch return;41 }) catch return;
43 // zig fmt: on42 // zig fmt: on
4443
src/Builtin.zig+10-10
...@@ -51,7 +51,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {...@@ -51,7 +51,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
51 const zig_backend = opts.zig_backend;51 const zig_backend = opts.zig_backend;
5252
53 @setEvalBranchQuota(4000);53 @setEvalBranchQuota(4000);
54 try buffer.writer().print(54 try buffer.print(
55 \\const std = @import("std");55 \\const std = @import("std");
56 \\/// Zig version. When writing code that supports multiple versions of Zig, prefer56 \\/// Zig version. When writing code that supports multiple versions of Zig, prefer
57 \\/// feature detection (i.e. with `@hasDecl` or `@hasField`) over version checks.57 \\/// feature detection (i.e. with `@hasDecl` or `@hasField`) over version checks.
...@@ -89,10 +89,10 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {...@@ -89,10 +89,10 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
89 const index = @as(std.Target.Cpu.Feature.Set.Index, @intCast(index_usize));89 const index = @as(std.Target.Cpu.Feature.Set.Index, @intCast(index_usize));
90 const is_enabled = target.cpu.features.isEnabled(index);90 const is_enabled = target.cpu.features.isEnabled(index);
91 if (is_enabled) {91 if (is_enabled) {
92 try buffer.writer().print(" .{p_},\n", .{std.zig.fmtId(feature.name)});92 try buffer.print(" .{p_},\n", .{std.zig.fmtId(feature.name)});
93 }93 }
94 }94 }
95 try buffer.writer().print(95 try buffer.print(
96 \\ }}),96 \\ }}),
97 \\}};97 \\}};
98 \\pub const os: std.Target.Os = .{{98 \\pub const os: std.Target.Os = .{{
...@@ -104,7 +104,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {...@@ -104,7 +104,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
104104
105 switch (target.os.versionRange()) {105 switch (target.os.versionRange()) {
106 .none => try buffer.appendSlice(" .none = {} },\n"),106 .none => try buffer.appendSlice(" .none = {} },\n"),
107 .semver => |semver| try buffer.writer().print(107 .semver => |semver| try buffer.print(
108 \\ .semver = .{{108 \\ .semver = .{{
109 \\ .min = .{{109 \\ .min = .{{
110 \\ .major = {},110 \\ .major = {},
...@@ -127,7 +127,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {...@@ -127,7 +127,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
127 semver.max.minor,127 semver.max.minor,
128 semver.max.patch,128 semver.max.patch,
129 }),129 }),
130 .linux => |linux| try buffer.writer().print(130 .linux => |linux| try buffer.print(
131 \\ .linux = .{{131 \\ .linux = .{{
132 \\ .range = .{{132 \\ .range = .{{
133 \\ .min = .{{133 \\ .min = .{{
...@@ -164,7 +164,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {...@@ -164,7 +164,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
164164
165 linux.android,165 linux.android,
166 }),166 }),
167 .hurd => |hurd| try buffer.writer().print(167 .hurd => |hurd| try buffer.print(
168 \\ .hurd = .{{168 \\ .hurd = .{{
169 \\ .range = .{{169 \\ .range = .{{
170 \\ .min = .{{170 \\ .min = .{{
...@@ -198,7 +198,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {...@@ -198,7 +198,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
198 hurd.glibc.minor,198 hurd.glibc.minor,
199 hurd.glibc.patch,199 hurd.glibc.patch,
200 }),200 }),
201 .windows => |windows| try buffer.writer().print(201 .windows => |windows| try buffer.print(
202 \\ .windows = .{{202 \\ .windows = .{{
203 \\ .min = {c},203 \\ .min = {c},
204 \\ .max = {c},204 \\ .max = {c},
...@@ -217,7 +217,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {...@@ -217,7 +217,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
217 );217 );
218218
219 if (target.dynamic_linker.get()) |dl| {219 if (target.dynamic_linker.get()) |dl| {
220 try buffer.writer().print(220 try buffer.print(
221 \\ .dynamic_linker = .init("{s}"),221 \\ .dynamic_linker = .init("{s}"),
222 \\}};222 \\}};
223 \\223 \\
...@@ -237,7 +237,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {...@@ -237,7 +237,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
237 // knows libc will provide it, and likewise c.zig will not export memcpy.237 // knows libc will provide it, and likewise c.zig will not export memcpy.
238 const link_libc = opts.link_libc;238 const link_libc = opts.link_libc;
239239
240 try buffer.writer().print(240 try buffer.print(
241 \\pub const object_format: std.Target.ObjectFormat = .{p_};241 \\pub const object_format: std.Target.ObjectFormat = .{p_};
242 \\pub const mode: std.builtin.OptimizeMode = .{p_};242 \\pub const mode: std.builtin.OptimizeMode = .{p_};
243 \\pub const link_libc = {};243 \\pub const link_libc = {};
...@@ -269,7 +269,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {...@@ -269,7 +269,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
269 });269 });
270270
271 if (target.os.tag == .wasi) {271 if (target.os.tag == .wasi) {
272 try buffer.writer().print(272 try buffer.print(
273 \\pub const wasi_exec_model: std.builtin.WasiExecModel = .{p_};273 \\pub const wasi_exec_model: std.builtin.WasiExecModel = .{p_};
274 \\274 \\
275 , .{std.zig.fmtId(@tagName(opts.wasi_exec_model))});275 , .{std.zig.fmtId(@tagName(opts.wasi_exec_model))});
src/Package/Fetch.zig+2-4
...@@ -1643,10 +1643,8 @@ fn dumpHashInfo(all_files: []const *const HashedFile) !void {...@@ -1643,10 +1643,8 @@ fn dumpHashInfo(all_files: []const *const HashedFile) !void {
1643 const w = bw.writer();1643 const w = bw.writer();
16441644
1645 for (all_files) |hashed_file| {1645 for (all_files) |hashed_file| {
1646 try w.print("{s}: {s}: {s}\n", .{1646 try w.print("{s}: {x}: {s}\n", .{
1647 @tagName(hashed_file.kind),1647 @tagName(hashed_file.kind), &hashed_file.hash, hashed_file.normalized_path,
1648 std.fmt.fmtSliceHexLower(&hashed_file.hash),
1649 hashed_file.normalized_path,
1650 });1648 });
1651 }1649 }
16521650
src/Package/Fetch/git.zig+1-1
...@@ -127,7 +127,7 @@ pub const Oid = union(Format) {...@@ -127,7 +127,7 @@ pub const Oid = union(Format) {
127 ) @TypeOf(writer).Error!void {127 ) @TypeOf(writer).Error!void {
128 _ = fmt;128 _ = fmt;
129 _ = options;129 _ = options;
130 try writer.print("{}", .{std.fmt.fmtSliceHexLower(oid.slice())});130 try writer.print("{x}", .{oid.slice()});
131 }131 }
132132
133 pub fn slice(oid: *const Oid) []const u8 {133 pub fn slice(oid: *const Oid) []const u8 {
src/Zcu/PerThread.zig+2-5
...@@ -477,11 +477,8 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {...@@ -477,11 +477,8 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
477 if (std.zig.srcHashEql(old_hash, new_hash)) {477 if (std.zig.srcHashEql(old_hash, new_hash)) {
478 break :hash_changed;478 break :hash_changed;
479 }479 }
480 log.debug("hash for (%{d} -> %{d}) changed: {} -> {}", .{480 log.debug("hash for (%{d} -> %{d}) changed: {x} -> {x}", .{
481 old_inst,481 old_inst, new_inst, &old_hash, &new_hash,
482 new_inst,
483 std.fmt.fmtSliceHexLower(&old_hash),
484 std.fmt.fmtSliceHexLower(&new_hash),
485 });482 });
486 }483 }
487 // The source hash associated with this instruction changed - invalidate relevant dependencies.484 // The source hash associated with this instruction changed - invalidate relevant dependencies.
src/arch/x86_64/encoder.zig+2-2
...@@ -1205,9 +1205,9 @@ pub const Vex = struct {...@@ -1205,9 +1205,9 @@ pub const Vex = struct {
1205fn expectEqualHexStrings(expected: []const u8, given: []const u8, assembly: []const u8) !void {1205fn expectEqualHexStrings(expected: []const u8, given: []const u8, assembly: []const u8) !void {
1206 assert(expected.len > 0);1206 assert(expected.len > 0);
1207 if (std.mem.eql(u8, expected, given)) return;1207 if (std.mem.eql(u8, expected, given)) return;
1208 const expected_fmt = try std.fmt.allocPrint(testing.allocator, "{x}", .{std.fmt.fmtSliceHexLower(expected)});1208 const expected_fmt = try std.fmt.allocPrint(testing.allocator, "{x}", .{expected});
1209 defer testing.allocator.free(expected_fmt);1209 defer testing.allocator.free(expected_fmt);
1210 const given_fmt = try std.fmt.allocPrint(testing.allocator, "{x}", .{std.fmt.fmtSliceHexLower(given)});1210 const given_fmt = try std.fmt.allocPrint(testing.allocator, "{x}", .{given});
1211 defer testing.allocator.free(given_fmt);1211 defer testing.allocator.free(given_fmt);
1212 const idx = std.mem.indexOfDiff(u8, expected_fmt, given_fmt).?;1212 const idx = std.mem.indexOfDiff(u8, expected_fmt, given_fmt).?;
1213 const padding = try testing.allocator.alloc(u8, idx + 5);1213 const padding = try testing.allocator.alloc(u8, idx + 5);
src/fmt.zig+3-37
...@@ -190,41 +190,7 @@ pub fn run(...@@ -190,41 +190,7 @@ pub fn run(
190 }190 }
191}191}
192192
193const FmtError = error{193fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool, dir: fs.Dir, sub_path: []const u8) anyerror!void {
194 SystemResources,
195 OperationAborted,
196 IoPending,
197 BrokenPipe,
198 Unexpected,
199 WouldBlock,
200 Canceled,
201 FileClosed,
202 DestinationAddressRequired,
203 DiskQuota,
204 FileTooBig,
205 MessageTooBig,
206 InputOutput,
207 NoSpaceLeft,
208 AccessDenied,
209 OutOfMemory,
210 RenameAcrossMountPoints,
211 ReadOnlyFileSystem,
212 LinkQuotaExceeded,
213 FileBusy,
214 EndOfStream,
215 Unseekable,
216 NotOpenForWriting,
217 UnsupportedEncoding,
218 InvalidEncoding,
219 ConnectionResetByPeer,
220 SocketNotConnected,
221 LockViolation,
222 NetNameDeleted,
223 InvalidArgument,
224 ProcessNotFound,
225} || fs.File.OpenError;
226
227fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool, dir: fs.Dir, sub_path: []const u8) FmtError!void {
228 fmtPathFile(fmt, file_path, check_mode, dir, sub_path) catch |err| switch (err) {194 fmtPathFile(fmt, file_path, check_mode, dir, sub_path) catch |err| switch (err) {
229 error.IsDir, error.AccessDenied => return fmtPathDir(fmt, file_path, check_mode, dir, sub_path),195 error.IsDir, error.AccessDenied => return fmtPathDir(fmt, file_path, check_mode, dir, sub_path),
230 else => {196 else => {
...@@ -241,7 +207,7 @@ fn fmtPathDir(...@@ -241,7 +207,7 @@ fn fmtPathDir(
241 check_mode: bool,207 check_mode: bool,
242 parent_dir: fs.Dir,208 parent_dir: fs.Dir,
243 parent_sub_path: []const u8,209 parent_sub_path: []const u8,
244) FmtError!void {210) anyerror!void {
245 var dir = try parent_dir.openDir(parent_sub_path, .{ .iterate = true });211 var dir = try parent_dir.openDir(parent_sub_path, .{ .iterate = true });
246 defer dir.close();212 defer dir.close();
247213
...@@ -277,7 +243,7 @@ fn fmtPathFile(...@@ -277,7 +243,7 @@ fn fmtPathFile(
277 check_mode: bool,243 check_mode: bool,
278 dir: fs.Dir,244 dir: fs.Dir,
279 sub_path: []const u8,245 sub_path: []const u8,
280) FmtError!void {246) anyerror!void {
281 const source_file = try dir.openFile(sub_path, .{});247 const source_file = try dir.openFile(sub_path, .{});
282 var file_closed = false;248 var file_closed = false;
283 errdefer if (!file_closed) source_file.close();249 errdefer if (!file_closed) source_file.close();
src/libs/mingw.zig+14-13
...@@ -388,7 +388,7 @@ pub fn libExists(...@@ -388,7 +388,7 @@ pub fn libExists(
388/// This function body is verbose but all it does is test 3 different paths and388/// This function body is verbose but all it does is test 3 different paths and
389/// see if a .def file exists.389/// see if a .def file exists.
390fn findDef(390fn findDef(
391 allocator: Allocator,391 gpa: Allocator,
392 target: *const std.Target,392 target: *const std.Target,
393 zig_lib_directory: Cache.Directory,393 zig_lib_directory: Cache.Directory,
394 lib_name: []const u8,394 lib_name: []const u8,
...@@ -401,7 +401,8 @@ fn findDef(...@@ -401,7 +401,8 @@ fn findDef(
401 else => unreachable,401 else => unreachable,
402 };402 };
403403
404 var override_path = std.ArrayList(u8).init(allocator);404 var override_path: std.io.AllocatingWriter = undefined;
405 const override_path_writer = override_path.init(gpa);
405 defer override_path.deinit();406 defer override_path.deinit();
406407
407 const s = path.sep_str;408 const s = path.sep_str;
...@@ -410,11 +411,11 @@ fn findDef(...@@ -410,11 +411,11 @@ fn findDef(
410 // Try the archtecture-specific path first.411 // Try the archtecture-specific path first.
411 const fmt_path = "libc" ++ s ++ "mingw" ++ s ++ "{s}" ++ s ++ "{s}.def";412 const fmt_path = "libc" ++ s ++ "mingw" ++ s ++ "{s}" ++ s ++ "{s}.def";
412 if (zig_lib_directory.path) |p| {413 if (zig_lib_directory.path) |p| {
413 try override_path.writer().print("{s}" ++ s ++ fmt_path, .{ p, lib_path, lib_name });414 try override_path_writer.print("{s}" ++ s ++ fmt_path, .{ p, lib_path, lib_name });
414 } else {415 } else {
415 try override_path.writer().print(fmt_path, .{ lib_path, lib_name });416 try override_path_writer.print(fmt_path, .{ lib_path, lib_name });
416 }417 }
417 if (std.fs.cwd().access(override_path.items, .{})) |_| {418 if (std.fs.cwd().access(override_path.getWritten(), .{})) |_| {
418 return override_path.toOwnedSlice();419 return override_path.toOwnedSlice();
419 } else |err| switch (err) {420 } else |err| switch (err) {
420 error.FileNotFound => {},421 error.FileNotFound => {},
...@@ -424,14 +425,14 @@ fn findDef(...@@ -424,14 +425,14 @@ fn findDef(
424425
425 {426 {
426 // Try the generic version.427 // Try the generic version.
427 override_path.shrinkRetainingCapacity(0);428 override_path.clearRetainingCapacity();
428 const fmt_path = "libc" ++ s ++ "mingw" ++ s ++ "lib-common" ++ s ++ "{s}.def";429 const fmt_path = "libc" ++ s ++ "mingw" ++ s ++ "lib-common" ++ s ++ "{s}.def";
429 if (zig_lib_directory.path) |p| {430 if (zig_lib_directory.path) |p| {
430 try override_path.writer().print("{s}" ++ s ++ fmt_path, .{ p, lib_name });431 try override_path_writer.print("{s}" ++ s ++ fmt_path, .{ p, lib_name });
431 } else {432 } else {
432 try override_path.writer().print(fmt_path, .{lib_name});433 try override_path_writer.print(fmt_path, .{lib_name});
433 }434 }
434 if (std.fs.cwd().access(override_path.items, .{})) |_| {435 if (std.fs.cwd().access(override_path.getWritten(), .{})) |_| {
435 return override_path.toOwnedSlice();436 return override_path.toOwnedSlice();
436 } else |err| switch (err) {437 } else |err| switch (err) {
437 error.FileNotFound => {},438 error.FileNotFound => {},
...@@ -441,14 +442,14 @@ fn findDef(...@@ -441,14 +442,14 @@ fn findDef(
441442
442 {443 {
443 // Try the generic version and preprocess it.444 // Try the generic version and preprocess it.
444 override_path.shrinkRetainingCapacity(0);445 override_path.clearRetainingCapacity();
445 const fmt_path = "libc" ++ s ++ "mingw" ++ s ++ "lib-common" ++ s ++ "{s}.def.in";446 const fmt_path = "libc" ++ s ++ "mingw" ++ s ++ "lib-common" ++ s ++ "{s}.def.in";
446 if (zig_lib_directory.path) |p| {447 if (zig_lib_directory.path) |p| {
447 try override_path.writer().print("{s}" ++ s ++ fmt_path, .{ p, lib_name });448 try override_path_writer.print("{s}" ++ s ++ fmt_path, .{ p, lib_name });
448 } else {449 } else {
449 try override_path.writer().print(fmt_path, .{lib_name});450 try override_path_writer.print(fmt_path, .{lib_name});
450 }451 }
451 if (std.fs.cwd().access(override_path.items, .{})) |_| {452 if (std.fs.cwd().access(override_path.getWritten(), .{})) |_| {
452 return override_path.toOwnedSlice();453 return override_path.toOwnedSlice();
453 } else |err| switch (err) {454 } else |err| switch (err) {
454 error.FileNotFound => {},455 error.FileNotFound => {},
src/link/Coff.zig+2-2
...@@ -830,8 +830,8 @@ fn debugMem(allocator: Allocator, handle: std.process.Child.Id, pvaddr: std.os.w...@@ -830,8 +830,8 @@ fn debugMem(allocator: Allocator, handle: std.process.Child.Id, pvaddr: std.os.w
830 const buffer = try allocator.alloc(u8, code.len);830 const buffer = try allocator.alloc(u8, code.len);
831 defer allocator.free(buffer);831 defer allocator.free(buffer);
832 const memread = try std.os.windows.ReadProcessMemory(handle, pvaddr, buffer);832 const memread = try std.os.windows.ReadProcessMemory(handle, pvaddr, buffer);
833 log.debug("to write: {x}", .{std.fmt.fmtSliceHexLower(code)});833 log.debug("to write: {x}", .{code});
834 log.debug("in memory: {x}", .{std.fmt.fmtSliceHexLower(memread)});834 log.debug("in memory: {x}", .{memread});
835}835}
836836
837fn writeMemProtected(handle: std.process.Child.Id, pvaddr: std.os.windows.LPVOID, code: []const u8) !void {837fn writeMemProtected(handle: std.process.Child.Id, pvaddr: std.os.windows.LPVOID, code: []const u8) !void {
src/link/MachO/dyld_info/Trie.zig+2-2
...@@ -336,9 +336,9 @@ const Edge = struct {...@@ -336,9 +336,9 @@ const Edge = struct {
336fn expectEqualHexStrings(expected: []const u8, given: []const u8) !void {336fn expectEqualHexStrings(expected: []const u8, given: []const u8) !void {
337 assert(expected.len > 0);337 assert(expected.len > 0);
338 if (mem.eql(u8, expected, given)) return;338 if (mem.eql(u8, expected, given)) return;
339 const expected_fmt = try std.fmt.allocPrint(testing.allocator, "{x}", .{std.fmt.fmtSliceHexLower(expected)});339 const expected_fmt = try std.fmt.allocPrint(testing.allocator, "{x}", .{expected});
340 defer testing.allocator.free(expected_fmt);340 defer testing.allocator.free(expected_fmt);
341 const given_fmt = try std.fmt.allocPrint(testing.allocator, "{x}", .{std.fmt.fmtSliceHexLower(given)});341 const given_fmt = try std.fmt.allocPrint(testing.allocator, "{x}", .{given});
342 defer testing.allocator.free(given_fmt);342 defer testing.allocator.free(given_fmt);
343 const idx = mem.indexOfDiff(u8, expected_fmt, given_fmt).?;343 const idx = mem.indexOfDiff(u8, expected_fmt, given_fmt).?;
344 const padding = try testing.allocator.alloc(u8, idx + 5);344 const padding = try testing.allocator.alloc(u8, idx + 5);
src/link/Wasm/Flush.zig+3-9
...@@ -1035,20 +1035,14 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {...@@ -1035,20 +1035,14 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
1035 var id: [16]u8 = undefined;1035 var id: [16]u8 = undefined;
1036 std.crypto.hash.sha3.TurboShake128(null).hash(binary_bytes.items, &id, .{});1036 std.crypto.hash.sha3.TurboShake128(null).hash(binary_bytes.items, &id, .{});
1037 var uuid: [36]u8 = undefined;1037 var uuid: [36]u8 = undefined;
1038 _ = try std.fmt.bufPrint(&uuid, "{s}-{s}-{s}-{s}-{s}", .{1038 _ = try std.fmt.bufPrint(&uuid, "{x}-{x}-{x}-{x}-{x}", .{
1039 std.fmt.fmtSliceHexLower(id[0..4]),1039 id[0..4], id[4..6], id[6..8], id[8..10], id[10..],
1040 std.fmt.fmtSliceHexLower(id[4..6]),
1041 std.fmt.fmtSliceHexLower(id[6..8]),
1042 std.fmt.fmtSliceHexLower(id[8..10]),
1043 std.fmt.fmtSliceHexLower(id[10..]),
1044 });1040 });
1045 try emitBuildIdSection(gpa, binary_bytes, &uuid);1041 try emitBuildIdSection(gpa, binary_bytes, &uuid);
1046 },1042 },
1047 .hexstring => |hs| {1043 .hexstring => |hs| {
1048 var buffer: [32 * 2]u8 = undefined;1044 var buffer: [32 * 2]u8 = undefined;
1049 const str = std.fmt.bufPrint(&buffer, "{s}", .{1045 const str = std.fmt.bufPrint(&buffer, "{x}", .{hs.toSlice()}) catch unreachable;
1050 std.fmt.fmtSliceHexLower(hs.toSlice()),
1051 }) catch unreachable;
1052 try emitBuildIdSection(gpa, binary_bytes, str);1046 try emitBuildIdSection(gpa, binary_bytes, str);
1053 },1047 },
1054 else => |mode| {1048 else => |mode| {
src/main.zig+73-58
...@@ -65,6 +65,9 @@ pub fn wasi_cwd() std.os.wasi.fd_t {...@@ -65,6 +65,9 @@ pub fn wasi_cwd() std.os.wasi.fd_t {
6565
66const fatal = std.process.fatal;66const fatal = std.process.fatal;
6767
68/// This can be global since stdout is a singleton.
69var stdout_buffer: [4096]u8 = undefined;
70
68/// Shaming all the locations that inappropriately use an O(N) search algorithm.71/// Shaming all the locations that inappropriately use an O(N) search algorithm.
69/// Please delete this and fix the compilation errors!72/// Please delete this and fix the compilation errors!
70pub const @"bad O(N)" = void;73pub const @"bad O(N)" = void;
...@@ -338,9 +341,7 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -338,9 +341,7 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
338 return cmdInit(gpa, arena, cmd_args);341 return cmdInit(gpa, arena, cmd_args);
339 } else if (mem.eql(u8, cmd, "targets")) {342 } else if (mem.eql(u8, cmd, "targets")) {
340 dev.check(.targets_command);343 dev.check(.targets_command);
341 const host = std.zig.resolveTargetQueryOrFatal(.{});344 return @import("print_targets.zig").cmdTargets(arena, cmd_args);
342 const stdout = io.getStdOut().writer();
343 return @import("print_targets.zig").cmdTargets(arena, cmd_args, stdout, &host);
344 } else if (mem.eql(u8, cmd, "version")) {345 } else if (mem.eql(u8, cmd, "version")) {
345 dev.check(.version_command);346 dev.check(.version_command);
346 try std.io.getStdOut().writeAll(build_options.version ++ "\n");347 try std.io.getStdOut().writeAll(build_options.version ++ "\n");
...@@ -351,7 +352,7 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -351,7 +352,7 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
351 } else if (mem.eql(u8, cmd, "env")) {352 } else if (mem.eql(u8, cmd, "env")) {
352 dev.check(.env_command);353 dev.check(.env_command);
353 verifyLibcxxCorrectlyLinked();354 verifyLibcxxCorrectlyLinked();
354 return @import("print_env.zig").cmdEnv(arena, cmd_args, io.getStdOut().writer());355 return @import("print_env.zig").cmdEnv(arena, cmd_args);
355 } else if (mem.eql(u8, cmd, "reduce")) {356 } else if (mem.eql(u8, cmd, "reduce")) {
356 return jitCmd(gpa, arena, cmd_args, .{357 return jitCmd(gpa, arena, cmd_args, .{
357 .cmd_name = "reduce",358 .cmd_name = "reduce",
...@@ -3334,9 +3335,8 @@ fn buildOutputType(...@@ -3334,9 +3335,8 @@ fn buildOutputType(
3334 var bin_digest: Cache.BinDigest = undefined;3335 var bin_digest: Cache.BinDigest = undefined;
3335 hasher.final(&bin_digest);3336 hasher.final(&bin_digest);
33363337
3337 const sub_path = try std.fmt.allocPrint(arena, "tmp" ++ sep ++ "{s}-stdin{s}", .{3338 const sub_path = try std.fmt.allocPrint(arena, "tmp" ++ sep ++ "{x}-stdin{s}", .{
3338 std.fmt.fmtSliceHexLower(&bin_digest),3339 &bin_digest, ext.canonicalName(target),
3339 ext.canonicalName(target),
3340 });3340 });
3341 try dirs.local_cache.handle.rename(dump_path, sub_path);3341 try dirs.local_cache.handle.rename(dump_path, sub_path);
33423342
...@@ -6061,6 +6061,11 @@ fn cmdAstCheck(...@@ -6061,6 +6061,11 @@ fn cmdAstCheck(
60616061
6062 const tree = try Ast.parse(arena, source, mode);6062 const tree = try Ast.parse(arena, source, mode);
60636063
6064 var bw: std.io.BufferedWriter = .{
6065 .unbuffered_writer = io.getStdOut().writer(),
6066 .buffer = &stdout_buffer,
6067 };
6068
6064 switch (mode) {6069 switch (mode) {
6065 .zig => {6070 .zig => {
6066 const zir = try AstGen.generate(arena, tree);6071 const zir = try AstGen.generate(arena, tree);
...@@ -6103,31 +6108,30 @@ fn cmdAstCheck(...@@ -6103,31 +6108,30 @@ fn cmdAstCheck(
6103 const extra_bytes = zir.extra.len * @sizeOf(u32);6108 const extra_bytes = zir.extra.len * @sizeOf(u32);
6104 const total_bytes = @sizeOf(Zir) + instruction_bytes + extra_bytes +6109 const total_bytes = @sizeOf(Zir) + instruction_bytes + extra_bytes +
6105 zir.string_bytes.len * @sizeOf(u8);6110 zir.string_bytes.len * @sizeOf(u8);
6106 const stdout = io.getStdOut();
6107 const fmtIntSizeBin = std.fmt.fmtIntSizeBin;
6108 // zig fmt: off6111 // zig fmt: off
6109 try stdout.writer().print(6112 try bw.print(
6110 \\# Source bytes: {}6113 \\# Source bytes: {Bi}
6111 \\# Tokens: {} ({})6114 \\# Tokens: {} ({Bi})
6112 \\# AST Nodes: {} ({})6115 \\# AST Nodes: {} ({Bi})
6113 \\# Total ZIR bytes: {}6116 \\# Total ZIR bytes: {Bi}
6114 \\# Instructions: {d} ({})6117 \\# Instructions: {d} ({Bi})
6115 \\# String Table Bytes: {}6118 \\# String Table Bytes: {}
6116 \\# Extra Data Items: {d} ({})6119 \\# Extra Data Items: {d} ({Bi})
6117 \\6120 \\
6118 , .{6121 , .{
6119 fmtIntSizeBin(source.len),6122 source.len,
6120 tree.tokens.len, fmtIntSizeBin(token_bytes),6123 tree.tokens.len, token_bytes,
6121 tree.nodes.len, fmtIntSizeBin(tree_bytes),6124 tree.nodes.len, tree_bytes,
6122 fmtIntSizeBin(total_bytes),6125 total_bytes,
6123 zir.instructions.len, fmtIntSizeBin(instruction_bytes),6126 zir.instructions.len, instruction_bytes,
6124 fmtIntSizeBin(zir.string_bytes.len),6127 zir.string_bytes.len,
6125 zir.extra.len, fmtIntSizeBin(extra_bytes),6128 zir.extra.len, extra_bytes,
6126 });6129 });
6127 // zig fmt: on6130 // zig fmt: on
6128 }6131 }
61296132
6130 try @import("print_zir.zig").renderAsTextToFile(arena, tree, zir, io.getStdOut());6133 try @import("print_zir.zig").renderAsText(arena, tree, zir, &bw);
6134 try bw.flush();
61316135
6132 if (zir.hasCompileErrors()) {6136 if (zir.hasCompileErrors()) {
6133 process.exit(1);6137 process.exit(1);
...@@ -6154,7 +6158,8 @@ fn cmdAstCheck(...@@ -6154,7 +6158,8 @@ fn cmdAstCheck(
6154 fatal("-t option only available in builds of zig with debug extensions", .{});6158 fatal("-t option only available in builds of zig with debug extensions", .{});
6155 }6159 }
61566160
6157 try @import("print_zoir.zig").renderToFile(zoir, arena, io.getStdOut());6161 try @import("print_zoir.zig").renderToWriter(zoir, arena, &bw);
6162 try bw.flush();
6158 return cleanExit();6163 return cleanExit();
6159 },6164 },
6160 }6165 }
...@@ -6275,11 +6280,13 @@ fn detectNativeCpuWithLLVM(...@@ -6275,11 +6280,13 @@ fn detectNativeCpuWithLLVM(
6275}6280}
62766281
6277fn printCpu(cpu: std.Target.Cpu) !void {6282fn printCpu(cpu: std.Target.Cpu) !void {
6278 var bw = io.bufferedWriter(io.getStdOut().writer());6283 var bw: std.io.BufferedWriter = .{
6279 const stdout = bw.writer();6284 .unbuffered_writer = io.getStdOut().writer(),
6285 .buffer = &stdout_buffer,
6286 };
62806287
6281 if (cpu.model.llvm_name) |llvm_name| {6288 if (cpu.model.llvm_name) |llvm_name| {
6282 try stdout.print("{s}\n", .{llvm_name});6289 try bw.print("{s}\n", .{llvm_name});
6283 }6290 }
62846291
6285 const all_features = cpu.arch.allFeaturesList();6292 const all_features = cpu.arch.allFeaturesList();
...@@ -6288,7 +6295,7 @@ fn printCpu(cpu: std.Target.Cpu) !void {...@@ -6288,7 +6295,7 @@ fn printCpu(cpu: std.Target.Cpu) !void {
6288 const index: std.Target.Cpu.Feature.Set.Index = @intCast(index_usize);6295 const index: std.Target.Cpu.Feature.Set.Index = @intCast(index_usize);
6289 const is_enabled = cpu.features.isEnabled(index);6296 const is_enabled = cpu.features.isEnabled(index);
6290 const plus_or_minus = "-+"[@intFromBool(is_enabled)];6297 const plus_or_minus = "-+"[@intFromBool(is_enabled)];
6291 try stdout.print("{c}{s}\n", .{ plus_or_minus, llvm_name });6298 try bw.print("{c}{s}\n", .{ plus_or_minus, llvm_name });
6292 }6299 }
62936300
6294 try bw.flush();6301 try bw.flush();
...@@ -6356,6 +6363,11 @@ fn cmdDumpZir(...@@ -6356,6 +6363,11 @@ fn cmdDumpZir(
63566363
6357 const zir = try Zcu.loadZirCache(arena, f);6364 const zir = try Zcu.loadZirCache(arena, f);
63586365
6366 var bw: std.io.BufferedWriter = .{
6367 .unbuffered_writer = io.getStdOut().writer(),
6368 .buffer = &stdout_buffer,
6369 };
6370
6359 {6371 {
6360 const instruction_bytes = zir.instructions.len *6372 const instruction_bytes = zir.instructions.len *
6361 // Here we don't use @sizeOf(Zir.Inst.Data) because it would include6373 // Here we don't use @sizeOf(Zir.Inst.Data) because it would include
...@@ -6364,25 +6376,24 @@ fn cmdDumpZir(...@@ -6364,25 +6376,24 @@ fn cmdDumpZir(
6364 const extra_bytes = zir.extra.len * @sizeOf(u32);6376 const extra_bytes = zir.extra.len * @sizeOf(u32);
6365 const total_bytes = @sizeOf(Zir) + instruction_bytes + extra_bytes +6377 const total_bytes = @sizeOf(Zir) + instruction_bytes + extra_bytes +
6366 zir.string_bytes.len * @sizeOf(u8);6378 zir.string_bytes.len * @sizeOf(u8);
6367 const stdout = io.getStdOut();
6368 const fmtIntSizeBin = std.fmt.fmtIntSizeBin;
6369 // zig fmt: off6379 // zig fmt: off
6370 try stdout.writer().print(6380 try bw.print(
6371 \\# Total ZIR bytes: {}6381 \\# Total ZIR bytes: {Bi}
6372 \\# Instructions: {d} ({})6382 \\# Instructions: {d} ({Bi})
6373 \\# String Table Bytes: {}6383 \\# String Table Bytes: {Bi}
6374 \\# Extra Data Items: {d} ({})6384 \\# Extra Data Items: {d} ({Bi})
6375 \\6385 \\
6376 , .{6386 , .{
6377 fmtIntSizeBin(total_bytes),6387 total_bytes,
6378 zir.instructions.len, fmtIntSizeBin(instruction_bytes),6388 zir.instructions.len, instruction_bytes,
6379 fmtIntSizeBin(zir.string_bytes.len),6389 zir.string_bytes.len,
6380 zir.extra.len, fmtIntSizeBin(extra_bytes),6390 zir.extra.len, extra_bytes,
6381 });6391 });
6382 // zig fmt: on6392 // zig fmt: on
6383 }6393 }
63846394
6385 return @import("print_zir.zig").renderAsTextToFile(arena, null, zir, io.getStdOut());6395 try @import("print_zir.zig").renderAsText(arena, null, zir, &bw);
6396 try bw.flush();
6386}6397}
63876398
6388/// This is only enabled for debug builds.6399/// This is only enabled for debug builds.
...@@ -6440,13 +6451,15 @@ fn cmdChangelist(...@@ -6440,13 +6451,15 @@ fn cmdChangelist(
6440 var inst_map: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .empty;6451 var inst_map: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .empty;
6441 try Zcu.mapOldZirToNew(arena, old_zir, new_zir, &inst_map);6452 try Zcu.mapOldZirToNew(arena, old_zir, new_zir, &inst_map);
64426453
6443 var bw = io.bufferedWriter(io.getStdOut().writer());6454 var bw: std.io.BufferedWriter = .{
6444 const stdout = bw.writer();6455 .unbuffered_writer = io.getStdOut().writer(),
6456 .buffer = &stdout_buffer,
6457 };
6445 {6458 {
6446 try stdout.print("Instruction mappings:\n", .{});6459 try bw.print("Instruction mappings:\n", .{});
6447 var it = inst_map.iterator();6460 var it = inst_map.iterator();
6448 while (it.next()) |entry| {6461 while (it.next()) |entry| {
6449 try stdout.print(" %{d} => %{d}\n", .{6462 try bw.print(" %{d} => %{d}\n", .{
6450 @intFromEnum(entry.key_ptr.*),6463 @intFromEnum(entry.key_ptr.*),
6451 @intFromEnum(entry.value_ptr.*),6464 @intFromEnum(entry.value_ptr.*),
6452 });6465 });
...@@ -6714,13 +6727,10 @@ fn accessFrameworkPath(...@@ -6714,13 +6727,10 @@ fn accessFrameworkPath(
67146727
6715 for (&[_][]const u8{ ".tbd", ".dylib", "" }) |ext| {6728 for (&[_][]const u8{ ".tbd", ".dylib", "" }) |ext| {
6716 test_path.clearRetainingCapacity();6729 test_path.clearRetainingCapacity();
6717 try test_path.writer().print("{s}" ++ sep ++ "{s}.framework" ++ sep ++ "{s}{s}", .{6730 try test_path.print("{s}" ++ sep ++ "{s}.framework" ++ sep ++ "{s}{s}", .{
6718 framework_dir_path,6731 framework_dir_path, framework_name, framework_name, ext,
6719 framework_name,
6720 framework_name,
6721 ext,
6722 });6732 });
6723 try checked_paths.writer().print("\n {s}", .{test_path.items});6733 try checked_paths.print("\n {s}", .{test_path.items});
6724 fs.cwd().access(test_path.items, .{}) catch |err| switch (err) {6734 fs.cwd().access(test_path.items, .{}) catch |err| switch (err) {
6725 error.FileNotFound => continue,6735 error.FileNotFound => continue,
6726 else => |e| fatal("unable to search for {s} framework '{s}': {s}", .{6736 else => |e| fatal("unable to search for {s} framework '{s}': {s}", .{
...@@ -7033,14 +7043,19 @@ fn cmdFetch(...@@ -7033,14 +7043,19 @@ fn cmdFetch(
7033 try fixups.append_string_after_node.put(gpa, manifest.version_node, dependencies_text);7043 try fixups.append_string_after_node.put(gpa, manifest.version_node, dependencies_text);
7034 }7044 }
70357045
7036 var rendered = std.ArrayList(u8).init(gpa);7046 var file = build_root.directory.handle.createFile(Package.Manifest.basename, .{}) catch |err| {
7037 defer rendered.deinit();7047 fatal("unable to create {s} file: {s}", .{ Package.Manifest.basename, err });
7038 try ast.renderToArrayList(&rendered, fixups);
7039
7040 build_root.directory.handle.writeFile(.{ .sub_path = Package.Manifest.basename, .data = rendered.items }) catch |err| {
7041 fatal("unable to write {s} file: {s}", .{ Package.Manifest.basename, @errorName(err) });
7042 };7048 };
70437049 defer file.close();
7050 var buffer: [4096]u8 = undefined;
7051 var bw: std.io.BufferedWriter = .{
7052 .unbuffered_writer = file.writer(),
7053 .buffer = &buffer,
7054 };
7055 ast.render(gpa, &bw, fixups) catch |err| fatal("failed to render AST to {s}: {s}", .{
7056 Package.Manifest.basename, err,
7057 });
7058 bw.flush() catch |err| fatal("failed to flush {s}: {s}", .{ Package.Manifest.basename, err });
7044 return cleanExit();7059 return cleanExit();
7045}7060}
70467061
src/print_env.zig+8-6
...@@ -4,7 +4,7 @@ const introspect = @import("introspect.zig");...@@ -4,7 +4,7 @@ const introspect = @import("introspect.zig");
4const Allocator = std.mem.Allocator;4const Allocator = std.mem.Allocator;
5const fatal = std.process.fatal;5const fatal = std.process.fatal;
66
7pub fn cmdEnv(arena: Allocator, args: []const []const u8, stdout: std.fs.File.Writer) !void {7pub fn cmdEnv(arena: Allocator, args: []const []const u8) !void {
8 _ = args;8 _ = args;
9 const cwd_path = try introspect.getResolvedCwd(arena);9 const cwd_path = try introspect.getResolvedCwd(arena);
10 const self_exe_path = try std.fs.selfExePathAlloc(arena);10 const self_exe_path = try std.fs.selfExePathAlloc(arena);
...@@ -21,10 +21,12 @@ pub fn cmdEnv(arena: Allocator, args: []const []const u8, stdout: std.fs.File.Wr...@@ -21,10 +21,12 @@ pub fn cmdEnv(arena: Allocator, args: []const []const u8, stdout: std.fs.File.Wr
21 const host = try std.zig.system.resolveTargetQuery(.{});21 const host = try std.zig.system.resolveTargetQuery(.{});
22 const triple = try host.zigTriple(arena);22 const triple = try host.zigTriple(arena);
2323
24 var bw = std.io.bufferedWriter(stdout);24 var buffer: [1024]u8 = undefined;
25 const w = bw.writer();25 var bw: std.io.BufferedWriter = .{
2626 .buffer = &buffer,
27 var jws = std.json.writeStream(w, .{ .whitespace = .indent_1 });27 .unbuffered_writer = std.io.getStdOut().writer(),
28 };
29 var jws = std.json.writeStream(bw, .{ .whitespace = .indent_1 });
2830
29 try jws.beginObject();31 try jws.beginObject();
3032
...@@ -55,7 +57,7 @@ pub fn cmdEnv(arena: Allocator, args: []const []const u8, stdout: std.fs.File.Wr...@@ -55,7 +57,7 @@ pub fn cmdEnv(arena: Allocator, args: []const []const u8, stdout: std.fs.File.Wr
55 try jws.endObject();57 try jws.endObject();
5658
57 try jws.endObject();59 try jws.endObject();
58 try w.writeByte('\n');60 try bw.writeByte('\n');
5961
60 try bw.flush();62 try bw.flush();
61}63}
src/print_targets.zig+26-30
...@@ -11,36 +11,36 @@ const assert = std.debug.assert;...@@ -11,36 +11,36 @@ const assert = std.debug.assert;
11const glibc = @import("libs/glibc.zig");11const glibc = @import("libs/glibc.zig");
12const introspect = @import("introspect.zig");12const introspect = @import("introspect.zig");
1313
14pub fn cmdTargets(14pub fn cmdTargets(arena: Allocator, args: []const []const u8) anyerror!void {
15 allocator: Allocator,
16 args: []const []const u8,
17 /// Output stream
18 stdout: anytype,
19 native_target: *const Target,
20) !void {
21 _ = args;15 _ = args;
22 var zig_lib_directory = introspect.findZigLibDir(allocator) catch |err| {16 const host = std.zig.resolveTargetQueryOrFatal(.{});
17 var buffer: [1024]u8 = undefined;
18 var bw: std.io.BufferedWriter = .{
19 .unbuffered_writer = io.getStdOut().writer(),
20 .buffer = &buffer,
21 };
22 try print(arena, &bw, host);
23 try bw.flush();
24}
25
26fn print(arena: Allocator, output: *std.io.BufferedWriter, host: *const Target) anyerror!void {
27 var zig_lib_directory = introspect.findZigLibDir(arena) catch |err| {
23 fatal("unable to find zig installation directory: {s}\n", .{@errorName(err)});28 fatal("unable to find zig installation directory: {s}\n", .{@errorName(err)});
24 };29 };
25 defer zig_lib_directory.handle.close();30 defer zig_lib_directory.handle.close();
26 defer allocator.free(zig_lib_directory.path.?);
2731
28 const abilists_contents = zig_lib_directory.handle.readFileAlloc(32 const abilists_contents = zig_lib_directory.handle.readFileAlloc(
29 allocator,33 arena,
30 glibc.abilists_path,34 glibc.abilists_path,
31 glibc.abilists_max_size,35 glibc.abilists_max_size,
32 ) catch |err| switch (err) {36 ) catch |err| switch (err) {
33 error.OutOfMemory => return error.OutOfMemory,37 error.OutOfMemory => return error.OutOfMemory,
34 else => fatal("unable to read " ++ glibc.abilists_path ++ ": {s}", .{@errorName(err)}),38 else => fatal("unable to read " ++ glibc.abilists_path ++ ": {s}", .{@errorName(err)}),
35 };39 };
36 defer allocator.free(abilists_contents);
3740
38 const glibc_abi = try glibc.loadMetaData(allocator, abilists_contents);41 const glibc_abi = try glibc.loadMetaData(arena, abilists_contents);
39 defer glibc_abi.destroy(allocator);
4042
41 var bw = io.bufferedWriter(stdout);43 var sz = std.zon.stringify.serializer(output, .{});
42 const w = bw.writer();
43 var sz = std.zon.stringify.serializer(w, .{});
4444
45 {45 {
46 var root_obj = try sz.beginStruct(.{});46 var root_obj = try sz.beginStruct(.{});
...@@ -52,10 +52,9 @@ pub fn cmdTargets(...@@ -52,10 +52,9 @@ pub fn cmdTargets(
52 {52 {
53 var libc_obj = try root_obj.beginTupleField("libc", .{});53 var libc_obj = try root_obj.beginTupleField("libc", .{});
54 for (std.zig.target.available_libcs) |libc| {54 for (std.zig.target.available_libcs) |libc| {
55 const tmp = try std.fmt.allocPrint(allocator, "{s}-{s}-{s}", .{55 const tmp = try std.fmt.allocPrint(arena, "{s}-{s}-{s}", .{
56 @tagName(libc.arch), @tagName(libc.os), @tagName(libc.abi),56 @tagName(libc.arch), @tagName(libc.os), @tagName(libc.abi),
57 });57 });
58 defer allocator.free(tmp);
59 try libc_obj.field(tmp, .{});58 try libc_obj.field(tmp, .{});
60 }59 }
61 try libc_obj.end();60 try libc_obj.end();
...@@ -64,8 +63,7 @@ pub fn cmdTargets(...@@ -64,8 +63,7 @@ pub fn cmdTargets(
64 {63 {
65 var glibc_obj = try root_obj.beginTupleField("glibc", .{});64 var glibc_obj = try root_obj.beginTupleField("glibc", .{});
66 for (glibc_abi.all_versions) |ver| {65 for (glibc_abi.all_versions) |ver| {
67 const tmp = try std.fmt.allocPrint(allocator, "{}", .{ver});66 const tmp = try std.fmt.allocPrint(arena, "{}", .{ver});
68 defer allocator.free(tmp);
69 try glibc_obj.field(tmp, .{});67 try glibc_obj.field(tmp, .{});
70 }68 }
71 try glibc_obj.end();69 try glibc_obj.end();
...@@ -105,21 +103,20 @@ pub fn cmdTargets(...@@ -105,21 +103,20 @@ pub fn cmdTargets(
105 {103 {
106 var native_obj = try root_obj.beginStructField("native", .{});104 var native_obj = try root_obj.beginStructField("native", .{});
107 {105 {
108 const triple = try native_target.zigTriple(allocator);106 const triple = try host.zigTriple(arena);
109 defer allocator.free(triple);
110 try native_obj.field("triple", triple, .{});107 try native_obj.field("triple", triple, .{});
111 }108 }
112 {109 {
113 var cpu_obj = try native_obj.beginStructField("cpu", .{});110 var cpu_obj = try native_obj.beginStructField("cpu", .{});
114 try cpu_obj.field("arch", @tagName(native_target.cpu.arch), .{});111 try cpu_obj.field("arch", @tagName(host.cpu.arch), .{});
115112
116 try cpu_obj.field("name", native_target.cpu.model.name, .{});113 try cpu_obj.field("name", host.cpu.model.name, .{});
117114
118 {115 {
119 var features = try native_obj.beginTupleField("features", .{});116 var features = try native_obj.beginTupleField("features", .{});
120 for (native_target.cpu.arch.allFeaturesList(), 0..) |feature, i_usize| {117 for (host.cpu.arch.allFeaturesList(), 0..) |feature, i_usize| {
121 const index = @as(Target.Cpu.Feature.Set.Index, @intCast(i_usize));118 const index = @as(Target.Cpu.Feature.Set.Index, @intCast(i_usize));
122 if (native_target.cpu.features.isEnabled(index)) {119 if (host.cpu.features.isEnabled(index)) {
123 try features.field(feature.name, .{});120 try features.field(feature.name, .{});
124 }121 }
125 }122 }
...@@ -128,14 +125,13 @@ pub fn cmdTargets(...@@ -128,14 +125,13 @@ pub fn cmdTargets(
128 try cpu_obj.end();125 try cpu_obj.end();
129 }126 }
130127
131 try native_obj.field("os", @tagName(native_target.os.tag), .{});128 try native_obj.field("os", @tagName(host.os.tag), .{});
132 try native_obj.field("abi", @tagName(native_target.abi), .{});129 try native_obj.field("abi", @tagName(host.abi), .{});
133 try native_obj.end();130 try native_obj.end();
134 }131 }
135132
136 try root_obj.end();133 try root_obj.end();
137 }134 }
138135
139 try w.writeByte('\n');136 try output.writeByte('\n');
140 return bw.flush();
141}137}
src/print_zir.zig+161-173
...@@ -9,13 +9,8 @@ const Zir = std.zig.Zir;...@@ -9,13 +9,8 @@ const Zir = std.zig.Zir;
9const Zcu = @import("Zcu.zig");9const Zcu = @import("Zcu.zig");
10const LazySrcLoc = Zcu.LazySrcLoc;10const LazySrcLoc = Zcu.LazySrcLoc;
1111
12/// Write human-readable, debug formatted ZIR code to a file.12/// Write human-readable, debug formatted ZIR code.
13pub fn renderAsTextToFile(13pub fn renderAsText(gpa: Allocator, tree: ?Ast, zir: Zir, bw: *std.io.BufferedWriter) anyerror!void {
14 gpa: Allocator,
15 tree: ?Ast,
16 zir: Zir,
17 fs_file: std.fs.File,
18) !void {
19 var arena = std.heap.ArenaAllocator.init(gpa);14 var arena = std.heap.ArenaAllocator.init(gpa);
20 defer arena.deinit();15 defer arena.deinit();
2116
...@@ -30,16 +25,13 @@ pub fn renderAsTextToFile(...@@ -30,16 +25,13 @@ pub fn renderAsTextToFile(
30 .recurse_blocks = true,25 .recurse_blocks = true,
31 };26 };
3227
33 var raw_stream = std.io.bufferedWriter(fs_file.writer());
34 const stream = raw_stream.writer();
35
36 const main_struct_inst: Zir.Inst.Index = .main_struct_inst;28 const main_struct_inst: Zir.Inst.Index = .main_struct_inst;
37 try stream.print("%{d} ", .{@intFromEnum(main_struct_inst)});29 try bw.print("%{d} ", .{@intFromEnum(main_struct_inst)});
38 try writer.writeInstToStream(stream, main_struct_inst);30 try writer.writeInstToStream(bw, main_struct_inst);
39 try stream.writeAll("\n");31 try bw.writeAll("\n");
40 const imports_index = zir.extra[@intFromEnum(Zir.ExtraIndex.imports)];32 const imports_index = zir.extra[@intFromEnum(Zir.ExtraIndex.imports)];
41 if (imports_index != 0) {33 if (imports_index != 0) {
42 try stream.writeAll("Imports:\n");34 try bw.writeAll("Imports:\n");
4335
44 const extra = zir.extraData(Zir.Inst.Imports, imports_index);36 const extra = zir.extraData(Zir.Inst.Imports, imports_index);
45 var extra_index = extra.end;37 var extra_index = extra.end;
...@@ -49,15 +41,13 @@ pub fn renderAsTextToFile(...@@ -49,15 +41,13 @@ pub fn renderAsTextToFile(
49 extra_index = item.end;41 extra_index = item.end;
5042
51 const import_path = zir.nullTerminatedString(item.data.name);43 const import_path = zir.nullTerminatedString(item.data.name);
52 try stream.print(" @import(\"{}\") ", .{44 try bw.print(" @import(\"{}\") ", .{
53 std.zig.fmtEscapes(import_path),45 std.zig.fmtEscapes(import_path),
54 });46 });
55 try writer.writeSrcTokAbs(stream, item.data.token);47 try writer.writeSrcTokAbs(bw, item.data.token);
56 try stream.writeAll("\n");48 try bw.writeAll("\n");
57 }49 }
58 }50 }
59
60 try raw_stream.flush();
61}51}
6252
63pub fn renderInstructionContext(53pub fn renderInstructionContext(
...@@ -67,7 +57,7 @@ pub fn renderInstructionContext(...@@ -67,7 +57,7 @@ pub fn renderInstructionContext(
67 scope_file: *Zcu.File,57 scope_file: *Zcu.File,
68 parent_decl_node: Ast.Node.Index,58 parent_decl_node: Ast.Node.Index,
69 indent: u32,59 indent: u32,
70 stream: anytype,60 bw: *std.io.BufferedWriter,
71) !void {61) !void {
72 var arena = std.heap.ArenaAllocator.init(gpa);62 var arena = std.heap.ArenaAllocator.init(gpa);
73 defer arena.deinit();63 defer arena.deinit();
...@@ -83,13 +73,13 @@ pub fn renderInstructionContext(...@@ -83,13 +73,13 @@ pub fn renderInstructionContext(
83 .recurse_blocks = true,73 .recurse_blocks = true,
84 };74 };
8575
86 try writer.writeBody(stream, block[0..block_index]);76 try writer.writeBody(bw, block[0..block_index]);
87 try stream.writeByteNTimes(' ', writer.indent - 2);77 try bw.splatByteAll(' ', writer.indent - 2);
88 try stream.print("> %{d} ", .{@intFromEnum(block[block_index])});78 try bw.print("> %{d} ", .{@intFromEnum(block[block_index])});
89 try writer.writeInstToStream(stream, block[block_index]);79 try writer.writeInstToStream(bw, block[block_index]);
90 try stream.writeByte('\n');80 try bw.writeByte('\n');
91 if (block_index + 1 < block.len) {81 if (block_index + 1 < block.len) {
92 try writer.writeBody(stream, block[block_index + 1 ..]);82 try writer.writeBody(bw, block[block_index + 1 ..]);
93 }83 }
94}84}
9585
...@@ -99,7 +89,7 @@ pub fn renderSingleInstruction(...@@ -99,7 +89,7 @@ pub fn renderSingleInstruction(
99 scope_file: *Zcu.File,89 scope_file: *Zcu.File,
100 parent_decl_node: Ast.Node.Index,90 parent_decl_node: Ast.Node.Index,
101 indent: u32,91 indent: u32,
102 stream: anytype,92 bw: *std.io.BufferedWriter,
103) !void {93) !void {
104 var arena = std.heap.ArenaAllocator.init(gpa);94 var arena = std.heap.ArenaAllocator.init(gpa);
105 defer arena.deinit();95 defer arena.deinit();
...@@ -115,8 +105,8 @@ pub fn renderSingleInstruction(...@@ -115,8 +105,8 @@ pub fn renderSingleInstruction(
115 .recurse_blocks = false,105 .recurse_blocks = false,
116 };106 };
117107
118 try stream.print("%{d} ", .{@intFromEnum(inst)});108 try bw.print("%{d} ", .{@intFromEnum(inst)});
119 try writer.writeInstToStream(stream, inst);109 try writer.writeInstToStream(bw, inst);
120}110}
121111
122const Writer = struct {112const Writer = struct {
...@@ -188,9 +178,9 @@ const Writer = struct {...@@ -188,9 +178,9 @@ const Writer = struct {
188178
189 fn writeInstToStream(179 fn writeInstToStream(
190 self: *Writer,180 self: *Writer,
191 stream: anytype,181 stream: *std.io.BufferedWriter,
192 inst: Zir.Inst.Index,182 inst: Zir.Inst.Index,
193 ) (@TypeOf(stream).Error || error{OutOfMemory})!void {183 ) anyerror!void {
194 const tags = self.code.instructions.items(.tag);184 const tags = self.code.instructions.items(.tag);
195 const tag = tags[@intFromEnum(inst)];185 const tag = tags[@intFromEnum(inst)];
196 try stream.print("= {s}(", .{@tagName(tags[@intFromEnum(inst)])});186 try stream.print("= {s}(", .{@tagName(tags[@intFromEnum(inst)])});
...@@ -518,7 +508,7 @@ const Writer = struct {...@@ -518,7 +508,7 @@ const Writer = struct {
518 }508 }
519 }509 }
520510
521 fn writeExtended(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {511 fn writeExtended(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
522 const extended = self.code.instructions.items(.data)[@intFromEnum(inst)].extended;512 const extended = self.code.instructions.items(.data)[@intFromEnum(inst)].extended;
523 try stream.print("{s}(", .{@tagName(extended.opcode)});513 try stream.print("{s}(", .{@tagName(extended.opcode)});
524 switch (extended.opcode) {514 switch (extended.opcode) {
...@@ -627,13 +617,13 @@ const Writer = struct {...@@ -627,13 +617,13 @@ const Writer = struct {
627 }617 }
628 }618 }
629619
630 fn writeExtNode(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {620 fn writeExtNode(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void {
631 try stream.writeAll(")) ");621 try stream.writeAll(")) ");
632 const src_node: Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand)));622 const src_node: Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand)));
633 try self.writeSrcNode(stream, src_node);623 try self.writeSrcNode(stream, src_node);
634 }624 }
635625
636 fn writeArrayInitElemType(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {626 fn writeArrayInitElemType(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
637 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].bin;627 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].bin;
638 try self.writeInstRef(stream, inst_data.lhs);628 try self.writeInstRef(stream, inst_data.lhs);
639 try stream.print(", {d})", .{@intFromEnum(inst_data.rhs)});629 try stream.print(", {d})", .{@intFromEnum(inst_data.rhs)});
...@@ -641,9 +631,9 @@ const Writer = struct {...@@ -641,9 +631,9 @@ const Writer = struct {
641631
642 fn writeUnNode(632 fn writeUnNode(
643 self: *Writer,633 self: *Writer,
644 stream: anytype,634 stream: *std.io.BufferedWriter,
645 inst: Zir.Inst.Index,635 inst: Zir.Inst.Index,
646 ) (@TypeOf(stream).Error || error{OutOfMemory})!void {636 ) anyerror!void {
647 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].un_node;637 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
648 try self.writeInstRef(stream, inst_data.operand);638 try self.writeInstRef(stream, inst_data.operand);
649 try stream.writeAll(") ");639 try stream.writeAll(") ");
...@@ -652,9 +642,9 @@ const Writer = struct {...@@ -652,9 +642,9 @@ const Writer = struct {
652642
653 fn writeUnTok(643 fn writeUnTok(
654 self: *Writer,644 self: *Writer,
655 stream: anytype,645 stream: *std.io.BufferedWriter,
656 inst: Zir.Inst.Index,646 inst: Zir.Inst.Index,
657 ) (@TypeOf(stream).Error || error{OutOfMemory})!void {647 ) anyerror!void {
658 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].un_tok;648 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].un_tok;
659 try self.writeInstRef(stream, inst_data.operand);649 try self.writeInstRef(stream, inst_data.operand);
660 try stream.writeAll(") ");650 try stream.writeAll(") ");
...@@ -663,9 +653,9 @@ const Writer = struct {...@@ -663,9 +653,9 @@ const Writer = struct {
663653
664 fn writeValidateDestructure(654 fn writeValidateDestructure(
665 self: *Writer,655 self: *Writer,
666 stream: anytype,656 stream: *std.io.BufferedWriter,
667 inst: Zir.Inst.Index,657 inst: Zir.Inst.Index,
668 ) (@TypeOf(stream).Error || error{OutOfMemory})!void {658 ) anyerror!void {
669 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;659 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
670 const extra = self.code.extraData(Zir.Inst.ValidateDestructure, inst_data.payload_index).data;660 const extra = self.code.extraData(Zir.Inst.ValidateDestructure, inst_data.payload_index).data;
671 try self.writeInstRef(stream, extra.operand);661 try self.writeInstRef(stream, extra.operand);
...@@ -677,9 +667,9 @@ const Writer = struct {...@@ -677,9 +667,9 @@ const Writer = struct {
677667
678 fn writeValidateArrayInitTy(668 fn writeValidateArrayInitTy(
679 self: *Writer,669 self: *Writer,
680 stream: anytype,670 stream: *std.io.BufferedWriter,
681 inst: Zir.Inst.Index,671 inst: Zir.Inst.Index,
682 ) (@TypeOf(stream).Error || error{OutOfMemory})!void {672 ) anyerror!void {
683 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;673 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
684 const extra = self.code.extraData(Zir.Inst.ArrayInit, inst_data.payload_index).data;674 const extra = self.code.extraData(Zir.Inst.ArrayInit, inst_data.payload_index).data;
685 try self.writeInstRef(stream, extra.ty);675 try self.writeInstRef(stream, extra.ty);
...@@ -689,9 +679,9 @@ const Writer = struct {...@@ -689,9 +679,9 @@ const Writer = struct {
689679
690 fn writeArrayTypeSentinel(680 fn writeArrayTypeSentinel(
691 self: *Writer,681 self: *Writer,
692 stream: anytype,682 stream: *std.io.BufferedWriter,
693 inst: Zir.Inst.Index,683 inst: Zir.Inst.Index,
694 ) (@TypeOf(stream).Error || error{OutOfMemory})!void {684 ) anyerror!void {
695 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;685 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
696 const extra = self.code.extraData(Zir.Inst.ArrayTypeSentinel, inst_data.payload_index).data;686 const extra = self.code.extraData(Zir.Inst.ArrayTypeSentinel, inst_data.payload_index).data;
697 try self.writeInstRef(stream, extra.len);687 try self.writeInstRef(stream, extra.len);
...@@ -705,9 +695,9 @@ const Writer = struct {...@@ -705,9 +695,9 @@ const Writer = struct {
705695
706 fn writePtrType(696 fn writePtrType(
707 self: *Writer,697 self: *Writer,
708 stream: anytype,698 stream: *std.io.BufferedWriter,
709 inst: Zir.Inst.Index,699 inst: Zir.Inst.Index,
710 ) (@TypeOf(stream).Error || error{OutOfMemory})!void {700 ) anyerror!void {
711 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].ptr_type;701 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].ptr_type;
712 const str_allowzero = if (inst_data.flags.is_allowzero) "allowzero, " else "";702 const str_allowzero = if (inst_data.flags.is_allowzero) "allowzero, " else "";
713 const str_const = if (!inst_data.flags.is_mutable) "const, " else "";703 const str_const = if (!inst_data.flags.is_mutable) "const, " else "";
...@@ -748,12 +738,12 @@ const Writer = struct {...@@ -748,12 +738,12 @@ const Writer = struct {
748 try self.writeSrcNode(stream, extra.data.src_node);738 try self.writeSrcNode(stream, extra.data.src_node);
749 }739 }
750740
751 fn writeInt(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {741 fn writeInt(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
752 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].int;742 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].int;
753 try stream.print("{d})", .{inst_data});743 try stream.print("{d})", .{inst_data});
754 }744 }
755745
756 fn writeIntBig(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {746 fn writeIntBig(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
757 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str;747 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str;
758 const byte_count = inst_data.len * @sizeOf(std.math.big.Limb);748 const byte_count = inst_data.len * @sizeOf(std.math.big.Limb);
759 const limb_bytes = self.code.string_bytes[@intFromEnum(inst_data.start)..][0..byte_count];749 const limb_bytes = self.code.string_bytes[@intFromEnum(inst_data.start)..][0..byte_count];
...@@ -772,12 +762,12 @@ const Writer = struct {...@@ -772,12 +762,12 @@ const Writer = struct {
772 try stream.print("{s})", .{as_string});762 try stream.print("{s})", .{as_string});
773 }763 }
774764
775 fn writeFloat(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {765 fn writeFloat(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
776 const number = self.code.instructions.items(.data)[@intFromEnum(inst)].float;766 const number = self.code.instructions.items(.data)[@intFromEnum(inst)].float;
777 try stream.print("{d})", .{number});767 try stream.print("{d})", .{number});
778 }768 }
779769
780 fn writeFloat128(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {770 fn writeFloat128(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
781 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;771 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
782 const extra = self.code.extraData(Zir.Inst.Float128, inst_data.payload_index).data;772 const extra = self.code.extraData(Zir.Inst.Float128, inst_data.payload_index).data;
783 const number = extra.get();773 const number = extra.get();
...@@ -788,15 +778,15 @@ const Writer = struct {...@@ -788,15 +778,15 @@ const Writer = struct {
788778
789 fn writeStr(779 fn writeStr(
790 self: *Writer,780 self: *Writer,
791 stream: anytype,781 stream: *std.io.BufferedWriter,
792 inst: Zir.Inst.Index,782 inst: Zir.Inst.Index,
793 ) (@TypeOf(stream).Error || error{OutOfMemory})!void {783 ) anyerror!void {
794 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str;784 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str;
795 const str = inst_data.get(self.code);785 const str = inst_data.get(self.code);
796 try stream.print("\"{}\")", .{std.zig.fmtEscapes(str)});786 try stream.print("\"{}\")", .{std.zig.fmtEscapes(str)});
797 }787 }
798788
799 fn writeSliceStart(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {789 fn writeSliceStart(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
800 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;790 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
801 const extra = self.code.extraData(Zir.Inst.SliceStart, inst_data.payload_index).data;791 const extra = self.code.extraData(Zir.Inst.SliceStart, inst_data.payload_index).data;
802 try self.writeInstRef(stream, extra.lhs);792 try self.writeInstRef(stream, extra.lhs);
...@@ -806,7 +796,7 @@ const Writer = struct {...@@ -806,7 +796,7 @@ const Writer = struct {
806 try self.writeSrcNode(stream, inst_data.src_node);796 try self.writeSrcNode(stream, inst_data.src_node);
807 }797 }
808798
809 fn writeSliceEnd(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {799 fn writeSliceEnd(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
810 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;800 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
811 const extra = self.code.extraData(Zir.Inst.SliceEnd, inst_data.payload_index).data;801 const extra = self.code.extraData(Zir.Inst.SliceEnd, inst_data.payload_index).data;
812 try self.writeInstRef(stream, extra.lhs);802 try self.writeInstRef(stream, extra.lhs);
...@@ -818,7 +808,7 @@ const Writer = struct {...@@ -818,7 +808,7 @@ const Writer = struct {
818 try self.writeSrcNode(stream, inst_data.src_node);808 try self.writeSrcNode(stream, inst_data.src_node);
819 }809 }
820810
821 fn writeSliceSentinel(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {811 fn writeSliceSentinel(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
822 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;812 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
823 const extra = self.code.extraData(Zir.Inst.SliceSentinel, inst_data.payload_index).data;813 const extra = self.code.extraData(Zir.Inst.SliceSentinel, inst_data.payload_index).data;
824 try self.writeInstRef(stream, extra.lhs);814 try self.writeInstRef(stream, extra.lhs);
...@@ -832,7 +822,7 @@ const Writer = struct {...@@ -832,7 +822,7 @@ const Writer = struct {
832 try self.writeSrcNode(stream, inst_data.src_node);822 try self.writeSrcNode(stream, inst_data.src_node);
833 }823 }
834824
835 fn writeSliceLength(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {825 fn writeSliceLength(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
836 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;826 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
837 const extra = self.code.extraData(Zir.Inst.SliceLength, inst_data.payload_index).data;827 const extra = self.code.extraData(Zir.Inst.SliceLength, inst_data.payload_index).data;
838 try self.writeInstRef(stream, extra.lhs);828 try self.writeInstRef(stream, extra.lhs);
...@@ -848,7 +838,7 @@ const Writer = struct {...@@ -848,7 +838,7 @@ const Writer = struct {
848 try self.writeSrcNode(stream, inst_data.src_node);838 try self.writeSrcNode(stream, inst_data.src_node);
849 }839 }
850840
851 fn writeUnionInit(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {841 fn writeUnionInit(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
852 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;842 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
853 const extra = self.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data;843 const extra = self.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data;
854 try self.writeInstRef(stream, extra.union_type);844 try self.writeInstRef(stream, extra.union_type);
...@@ -860,7 +850,7 @@ const Writer = struct {...@@ -860,7 +850,7 @@ const Writer = struct {
860 try self.writeSrcNode(stream, inst_data.src_node);850 try self.writeSrcNode(stream, inst_data.src_node);
861 }851 }
862852
863 fn writeShuffle(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {853 fn writeShuffle(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
864 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;854 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
865 const extra = self.code.extraData(Zir.Inst.Shuffle, inst_data.payload_index).data;855 const extra = self.code.extraData(Zir.Inst.Shuffle, inst_data.payload_index).data;
866 try self.writeInstRef(stream, extra.elem_type);856 try self.writeInstRef(stream, extra.elem_type);
...@@ -874,7 +864,7 @@ const Writer = struct {...@@ -874,7 +864,7 @@ const Writer = struct {
874 try self.writeSrcNode(stream, inst_data.src_node);864 try self.writeSrcNode(stream, inst_data.src_node);
875 }865 }
876866
877 fn writeSelect(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {867 fn writeSelect(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void {
878 const extra = self.code.extraData(Zir.Inst.Select, extended.operand).data;868 const extra = self.code.extraData(Zir.Inst.Select, extended.operand).data;
879 try self.writeInstRef(stream, extra.elem_type);869 try self.writeInstRef(stream, extra.elem_type);
880 try stream.writeAll(", ");870 try stream.writeAll(", ");
...@@ -887,7 +877,7 @@ const Writer = struct {...@@ -887,7 +877,7 @@ const Writer = struct {
887 try self.writeSrcNode(stream, extra.node);877 try self.writeSrcNode(stream, extra.node);
888 }878 }
889879
890 fn writeMulAdd(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {880 fn writeMulAdd(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
891 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;881 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
892 const extra = self.code.extraData(Zir.Inst.MulAdd, inst_data.payload_index).data;882 const extra = self.code.extraData(Zir.Inst.MulAdd, inst_data.payload_index).data;
893 try self.writeInstRef(stream, extra.mulend1);883 try self.writeInstRef(stream, extra.mulend1);
...@@ -899,7 +889,7 @@ const Writer = struct {...@@ -899,7 +889,7 @@ const Writer = struct {
899 try self.writeSrcNode(stream, inst_data.src_node);889 try self.writeSrcNode(stream, inst_data.src_node);
900 }890 }
901891
902 fn writeBuiltinCall(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {892 fn writeBuiltinCall(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
903 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;893 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
904 const extra = self.code.extraData(Zir.Inst.BuiltinCall, inst_data.payload_index).data;894 const extra = self.code.extraData(Zir.Inst.BuiltinCall, inst_data.payload_index).data;
905895
...@@ -915,7 +905,7 @@ const Writer = struct {...@@ -915,7 +905,7 @@ const Writer = struct {
915 try self.writeSrcNode(stream, inst_data.src_node);905 try self.writeSrcNode(stream, inst_data.src_node);
916 }906 }
917907
918 fn writeFieldParentPtr(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {908 fn writeFieldParentPtr(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void {
919 const extra = self.code.extraData(Zir.Inst.FieldParentPtr, extended.operand).data;909 const extra = self.code.extraData(Zir.Inst.FieldParentPtr, extended.operand).data;
920 const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).@"struct".backing_integer.?;910 const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).@"struct".backing_integer.?;
921 const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));911 const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));
...@@ -932,7 +922,7 @@ const Writer = struct {...@@ -932,7 +922,7 @@ const Writer = struct {
932 try self.writeSrcNode(stream, extra.src_node);922 try self.writeSrcNode(stream, extra.src_node);
933 }923 }
934924
935 fn writeBuiltinAsyncCall(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {925 fn writeBuiltinAsyncCall(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void {
936 const extra = self.code.extraData(Zir.Inst.AsyncCall, extended.operand).data;926 const extra = self.code.extraData(Zir.Inst.AsyncCall, extended.operand).data;
937 try self.writeInstRef(stream, extra.frame_buffer);927 try self.writeInstRef(stream, extra.frame_buffer);
938 try stream.writeAll(", ");928 try stream.writeAll(", ");
...@@ -945,7 +935,7 @@ const Writer = struct {...@@ -945,7 +935,7 @@ const Writer = struct {
945 try self.writeSrcNode(stream, extra.node);935 try self.writeSrcNode(stream, extra.node);
946 }936 }
947937
948 fn writeParam(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {938 fn writeParam(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
949 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_tok;939 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_tok;
950 const extra = self.code.extraData(Zir.Inst.Param, inst_data.payload_index);940 const extra = self.code.extraData(Zir.Inst.Param, inst_data.payload_index);
951 const body = self.code.bodySlice(extra.end, extra.data.type.body_len);941 const body = self.code.bodySlice(extra.end, extra.data.type.body_len);
...@@ -960,7 +950,7 @@ const Writer = struct {...@@ -960,7 +950,7 @@ const Writer = struct {
960 try self.writeSrcTok(stream, inst_data.src_tok);950 try self.writeSrcTok(stream, inst_data.src_tok);
961 }951 }
962952
963 fn writePlNodeBin(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {953 fn writePlNodeBin(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
964 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;954 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
965 const extra = self.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;955 const extra = self.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
966 try self.writeInstRef(stream, extra.lhs);956 try self.writeInstRef(stream, extra.lhs);
...@@ -970,7 +960,7 @@ const Writer = struct {...@@ -970,7 +960,7 @@ const Writer = struct {
970 try self.writeSrcNode(stream, inst_data.src_node);960 try self.writeSrcNode(stream, inst_data.src_node);
971 }961 }
972962
973 fn writePlNodeMultiOp(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {963 fn writePlNodeMultiOp(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
974 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;964 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
975 const extra = self.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);965 const extra = self.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);
976 const args = self.code.refSlice(extra.end, extra.data.operands_len);966 const args = self.code.refSlice(extra.end, extra.data.operands_len);
...@@ -983,7 +973,7 @@ const Writer = struct {...@@ -983,7 +973,7 @@ const Writer = struct {
983 try self.writeSrcNode(stream, inst_data.src_node);973 try self.writeSrcNode(stream, inst_data.src_node);
984 }974 }
985975
986 fn writeArrayMul(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {976 fn writeArrayMul(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
987 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;977 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
988 const extra = self.code.extraData(Zir.Inst.ArrayMul, inst_data.payload_index).data;978 const extra = self.code.extraData(Zir.Inst.ArrayMul, inst_data.payload_index).data;
989 try self.writeInstRef(stream, extra.res_ty);979 try self.writeInstRef(stream, extra.res_ty);
...@@ -995,13 +985,13 @@ const Writer = struct {...@@ -995,13 +985,13 @@ const Writer = struct {
995 try self.writeSrcNode(stream, inst_data.src_node);985 try self.writeSrcNode(stream, inst_data.src_node);
996 }986 }
997987
998 fn writeElemValImm(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {988 fn writeElemValImm(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
999 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].elem_val_imm;989 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].elem_val_imm;
1000 try self.writeInstRef(stream, inst_data.operand);990 try self.writeInstRef(stream, inst_data.operand);
1001 try stream.print(", {d})", .{inst_data.idx});991 try stream.print(", {d})", .{inst_data.idx});
1002 }992 }
1003993
1004 fn writeArrayInitElemPtr(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {994 fn writeArrayInitElemPtr(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
1005 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;995 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
1006 const extra = self.code.extraData(Zir.Inst.ElemPtrImm, inst_data.payload_index).data;996 const extra = self.code.extraData(Zir.Inst.ElemPtrImm, inst_data.payload_index).data;
1007997
...@@ -1010,7 +1000,7 @@ const Writer = struct {...@@ -1010,7 +1000,7 @@ const Writer = struct {
1010 try self.writeSrcNode(stream, inst_data.src_node);1000 try self.writeSrcNode(stream, inst_data.src_node);
1011 }1001 }
10121002
1013 fn writePlNodeExport(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {1003 fn writePlNodeExport(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
1014 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;1004 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
1015 const extra = self.code.extraData(Zir.Inst.Export, inst_data.payload_index).data;1005 const extra = self.code.extraData(Zir.Inst.Export, inst_data.payload_index).data;
10161006
...@@ -1021,7 +1011,7 @@ const Writer = struct {...@@ -1021,7 +1011,7 @@ const Writer = struct {
1021 try self.writeSrcNode(stream, inst_data.src_node);1011 try self.writeSrcNode(stream, inst_data.src_node);
1022 }1012 }
10231013
1024 fn writeValidateArrayInitRefTy(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {1014 fn writeValidateArrayInitRefTy(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
1025 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;1015 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
1026 const extra = self.code.extraData(Zir.Inst.ArrayInitRefTy, inst_data.payload_index).data;1016 const extra = self.code.extraData(Zir.Inst.ArrayInitRefTy, inst_data.payload_index).data;
10271017
...@@ -1031,7 +1021,7 @@ const Writer = struct {...@@ -1031,7 +1021,7 @@ const Writer = struct {
1031 try self.writeSrcNode(stream, inst_data.src_node);1021 try self.writeSrcNode(stream, inst_data.src_node);
1032 }1022 }
10331023
1034 fn writeStructInit(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {1024 fn writeStructInit(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
1035 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;1025 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
1036 const extra = self.code.extraData(Zir.Inst.StructInit, inst_data.payload_index);1026 const extra = self.code.extraData(Zir.Inst.StructInit, inst_data.payload_index);
1037 var field_i: u32 = 0;1027 var field_i: u32 = 0;
...@@ -1055,7 +1045,7 @@ const Writer = struct {...@@ -1055,7 +1045,7 @@ const Writer = struct {
1055 try self.writeSrcNode(stream, inst_data.src_node);1045 try self.writeSrcNode(stream, inst_data.src_node);
1056 }1046 }
10571047
1058 fn writeCmpxchg(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {1048 fn writeCmpxchg(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void {
1059 const extra = self.code.extraData(Zir.Inst.Cmpxchg, extended.operand).data;1049 const extra = self.code.extraData(Zir.Inst.Cmpxchg, extended.operand).data;
10601050
1061 try self.writeInstRef(stream, extra.ptr);1051 try self.writeInstRef(stream, extra.ptr);
...@@ -1071,7 +1061,7 @@ const Writer = struct {...@@ -1071,7 +1061,7 @@ const Writer = struct {
1071 try self.writeSrcNode(stream, extra.node);1061 try self.writeSrcNode(stream, extra.node);
1072 }1062 }
10731063
1074 fn writePtrCastFull(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {1064 fn writePtrCastFull(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void {
1075 const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).@"struct".backing_integer.?;1065 const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).@"struct".backing_integer.?;
1076 const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));1066 const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));
1077 const extra = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;1067 const extra = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;
...@@ -1087,7 +1077,7 @@ const Writer = struct {...@@ -1087,7 +1077,7 @@ const Writer = struct {
1087 try self.writeSrcNode(stream, extra.node);1077 try self.writeSrcNode(stream, extra.node);
1088 }1078 }
10891079
1090 fn writePtrCastNoDest(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {1080 fn writePtrCastNoDest(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void {
1091 const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).@"struct".backing_integer.?;1081 const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).@"struct".backing_integer.?;
1092 const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));1082 const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));
1093 const extra = self.code.extraData(Zir.Inst.UnNode, extended.operand).data;1083 const extra = self.code.extraData(Zir.Inst.UnNode, extended.operand).data;
...@@ -1098,7 +1088,7 @@ const Writer = struct {...@@ -1098,7 +1088,7 @@ const Writer = struct {
1098 try self.writeSrcNode(stream, extra.node);1088 try self.writeSrcNode(stream, extra.node);
1099 }1089 }
11001090
1101 fn writeAtomicLoad(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {1091 fn writeAtomicLoad(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
1102 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;1092 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
1103 const extra = self.code.extraData(Zir.Inst.AtomicLoad, inst_data.payload_index).data;1093 const extra = self.code.extraData(Zir.Inst.AtomicLoad, inst_data.payload_index).data;
11041094
...@@ -1111,7 +1101,7 @@ const Writer = struct {...@@ -1111,7 +1101,7 @@ const Writer = struct {
1111 try self.writeSrcNode(stream, inst_data.src_node);1101 try self.writeSrcNode(stream, inst_data.src_node);
1112 }1102 }
11131103
1114 fn writeAtomicStore(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {1104 fn writeAtomicStore(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
1115 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;1105 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
1116 const extra = self.code.extraData(Zir.Inst.AtomicStore, inst_data.payload_index).data;1106 const extra = self.code.extraData(Zir.Inst.AtomicStore, inst_data.payload_index).data;
11171107
...@@ -1124,7 +1114,7 @@ const Writer = struct {...@@ -1124,7 +1114,7 @@ const Writer = struct {
1124 try self.writeSrcNode(stream, inst_data.src_node);1114 try self.writeSrcNode(stream, inst_data.src_node);
1125 }1115 }
11261116
1127 fn writeAtomicRmw(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {1117 fn writeAtomicRmw(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
1128 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;1118 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
1129 const extra = self.code.extraData(Zir.Inst.AtomicRmw, inst_data.payload_index).data;1119 const extra = self.code.extraData(Zir.Inst.AtomicRmw, inst_data.payload_index).data;
11301120
...@@ -1139,7 +1129,7 @@ const Writer = struct {...@@ -1139,7 +1129,7 @@ const Writer = struct {
1139 try self.writeSrcNode(stream, inst_data.src_node);1129 try self.writeSrcNode(stream, inst_data.src_node);
1140 }1130 }
11411131
1142 fn writeStructInitAnon(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {1132 fn writeStructInitAnon(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
1143 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;1133 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
1144 const extra = self.code.extraData(Zir.Inst.StructInitAnon, inst_data.payload_index);1134 const extra = self.code.extraData(Zir.Inst.StructInitAnon, inst_data.payload_index);
1145 var field_i: u32 = 0;1135 var field_i: u32 = 0;
...@@ -1160,7 +1150,7 @@ const Writer = struct {...@@ -1160,7 +1150,7 @@ const Writer = struct {
1160 try self.writeSrcNode(stream, inst_data.src_node);1150 try self.writeSrcNode(stream, inst_data.src_node);
1161 }1151 }
11621152
1163 fn writeStructInitFieldType(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {1153 fn writeStructInitFieldType(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
1164 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;1154 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
1165 const extra = self.code.extraData(Zir.Inst.FieldType, inst_data.payload_index).data;1155 const extra = self.code.extraData(Zir.Inst.FieldType, inst_data.payload_index).data;
1166 try self.writeInstRef(stream, extra.container_type);1156 try self.writeInstRef(stream, extra.container_type);
...@@ -1169,7 +1159,7 @@ const Writer = struct {...@@ -1169,7 +1159,7 @@ const Writer = struct {
1169 try self.writeSrcNode(stream, inst_data.src_node);1159 try self.writeSrcNode(stream, inst_data.src_node);
1170 }1160 }
11711161
1172 fn writeFieldTypeRef(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {1162 fn writeFieldTypeRef(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
1173 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;1163 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
1174 const extra = self.code.extraData(Zir.Inst.FieldTypeRef, inst_data.payload_index).data;1164 const extra = self.code.extraData(Zir.Inst.FieldTypeRef, inst_data.payload_index).data;
1175 try self.writeInstRef(stream, extra.container_type);1165 try self.writeInstRef(stream, extra.container_type);
...@@ -1179,7 +1169,7 @@ const Writer = struct {...@@ -1179,7 +1169,7 @@ const Writer = struct {
1179 try self.writeSrcNode(stream, inst_data.src_node);1169 try self.writeSrcNode(stream, inst_data.src_node);
1180 }1170 }
11811171
1182 fn writeNodeMultiOp(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {1172 fn writeNodeMultiOp(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void {
1183 const extra = self.code.extraData(Zir.Inst.NodeMultiOp, extended.operand);1173 const extra = self.code.extraData(Zir.Inst.NodeMultiOp, extended.operand);
1184 const operands = self.code.refSlice(extra.end, extended.small);1174 const operands = self.code.refSlice(extra.end, extended.small);
11851175
...@@ -1193,9 +1183,9 @@ const Writer = struct {...@@ -1193,9 +1183,9 @@ const Writer = struct {
11931183
1194 fn writeInstNode(1184 fn writeInstNode(
1195 self: *Writer,1185 self: *Writer,
1196 stream: anytype,1186 stream: *std.io.BufferedWriter,
1197 inst: Zir.Inst.Index,1187 inst: Zir.Inst.Index,
1198 ) (@TypeOf(stream).Error || error{OutOfMemory})!void {1188 ) anyerror!void {
1199 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].inst_node;1189 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].inst_node;
1200 try self.writeInstIndex(stream, inst_data.inst);1190 try self.writeInstIndex(stream, inst_data.inst);
1201 try stream.writeAll(") ");1191 try stream.writeAll(") ");
...@@ -1204,7 +1194,7 @@ const Writer = struct {...@@ -1204,7 +1194,7 @@ const Writer = struct {
12041194
1205 fn writeAsm(1195 fn writeAsm(
1206 self: *Writer,1196 self: *Writer,
1207 stream: anytype,1197 stream: *std.io.BufferedWriter,
1208 extended: Zir.Inst.Extended.InstData,1198 extended: Zir.Inst.Extended.InstData,
1209 tmpl_is_expr: bool,1199 tmpl_is_expr: bool,
1210 ) !void {1200 ) !void {
...@@ -1282,7 +1272,7 @@ const Writer = struct {...@@ -1282,7 +1272,7 @@ const Writer = struct {
1282 try self.writeSrcNode(stream, extra.data.src_node);1272 try self.writeSrcNode(stream, extra.data.src_node);
1283 }1273 }
12841274
1285 fn writeOverflowArithmetic(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {1275 fn writeOverflowArithmetic(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void {
1286 const extra = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;1276 const extra = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;
12871277
1288 try self.writeInstRef(stream, extra.lhs);1278 try self.writeInstRef(stream, extra.lhs);
...@@ -1294,7 +1284,7 @@ const Writer = struct {...@@ -1294,7 +1284,7 @@ const Writer = struct {
12941284
1295 fn writeCall(1285 fn writeCall(
1296 self: *Writer,1286 self: *Writer,
1297 stream: anytype,1287 stream: *std.io.BufferedWriter,
1298 inst: Zir.Inst.Index,1288 inst: Zir.Inst.Index,
1299 comptime kind: enum { direct, field },1289 comptime kind: enum { direct, field },
1300 ) !void {1290 ) !void {
...@@ -1328,7 +1318,7 @@ const Writer = struct {...@@ -1328,7 +1318,7 @@ const Writer = struct {
1328 var i: usize = 0;1318 var i: usize = 0;
1329 var arg_start: u32 = args_len;1319 var arg_start: u32 = args_len;
1330 while (i < args_len) : (i += 1) {1320 while (i < args_len) : (i += 1) {
1331 try stream.writeByteNTimes(' ', self.indent);1321 try stream.splatByteAll(' ', self.indent);
1332 const arg_end = self.code.extra[extra.end + i];1322 const arg_end = self.code.extra[extra.end + i];
1333 defer arg_start = arg_end;1323 defer arg_start = arg_end;
1334 const arg_body = body[arg_start..arg_end];1324 const arg_body = body[arg_start..arg_end];
...@@ -1338,14 +1328,14 @@ const Writer = struct {...@@ -1338,14 +1328,14 @@ const Writer = struct {
1338 }1328 }
1339 self.indent -= 2;1329 self.indent -= 2;
1340 if (args_len != 0) {1330 if (args_len != 0) {
1341 try stream.writeByteNTimes(' ', self.indent);1331 try stream.splatByteAll(' ', self.indent);
1342 }1332 }
13431333
1344 try stream.writeAll("]) ");1334 try stream.writeAll("]) ");
1345 try self.writeSrcNode(stream, inst_data.src_node);1335 try self.writeSrcNode(stream, inst_data.src_node);
1346 }1336 }
13471337
1348 fn writeBlock(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {1338 fn writeBlock(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
1349 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;1339 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
1350 const extra = self.code.extraData(Zir.Inst.Block, inst_data.payload_index);1340 const extra = self.code.extraData(Zir.Inst.Block, inst_data.payload_index);
1351 const body = self.code.bodySlice(extra.end, extra.data.body_len);1341 const body = self.code.bodySlice(extra.end, extra.data.body_len);
...@@ -1354,7 +1344,7 @@ const Writer = struct {...@@ -1354,7 +1344,7 @@ const Writer = struct {
1354 try self.writeSrcNode(stream, inst_data.src_node);1344 try self.writeSrcNode(stream, inst_data.src_node);
1355 }1345 }
13561346
1357 fn writeBlockComptime(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {1347 fn writeBlockComptime(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
1358 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;1348 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
1359 const extra = self.code.extraData(Zir.Inst.BlockComptime, inst_data.payload_index);1349 const extra = self.code.extraData(Zir.Inst.BlockComptime, inst_data.payload_index);
1360 const body = self.code.bodySlice(extra.end, extra.data.body_len);1350 const body = self.code.bodySlice(extra.end, extra.data.body_len);
...@@ -1364,7 +1354,7 @@ const Writer = struct {...@@ -1364,7 +1354,7 @@ const Writer = struct {
1364 try self.writeSrcNode(stream, inst_data.src_node);1354 try self.writeSrcNode(stream, inst_data.src_node);
1365 }1355 }
13661356
1367 fn writeCondBr(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {1357 fn writeCondBr(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
1368 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;1358 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
1369 const extra = self.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);1359 const extra = self.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);
1370 const then_body = self.code.bodySlice(extra.end, extra.data.then_body_len);1360 const then_body = self.code.bodySlice(extra.end, extra.data.then_body_len);
...@@ -1378,7 +1368,7 @@ const Writer = struct {...@@ -1378,7 +1368,7 @@ const Writer = struct {
1378 try self.writeSrcNode(stream, inst_data.src_node);1368 try self.writeSrcNode(stream, inst_data.src_node);
1379 }1369 }
13801370
1381 fn writeTry(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {1371 fn writeTry(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
1382 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;1372 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
1383 const extra = self.code.extraData(Zir.Inst.Try, inst_data.payload_index);1373 const extra = self.code.extraData(Zir.Inst.Try, inst_data.payload_index);
1384 const body = self.code.bodySlice(extra.end, extra.data.body_len);1374 const body = self.code.bodySlice(extra.end, extra.data.body_len);
...@@ -1389,7 +1379,7 @@ const Writer = struct {...@@ -1389,7 +1379,7 @@ const Writer = struct {
1389 try self.writeSrcNode(stream, inst_data.src_node);1379 try self.writeSrcNode(stream, inst_data.src_node);
1390 }1380 }
13911381
1392 fn writeStructDecl(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {1382 fn writeStructDecl(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void {
1393 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);1383 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
13941384
1395 const extra = self.code.extraData(Zir.Inst.StructDecl, extended.operand);1385 const extra = self.code.extraData(Zir.Inst.StructDecl, extended.operand);
...@@ -1405,7 +1395,7 @@ const Writer = struct {...@@ -1405,7 +1395,7 @@ const Writer = struct {
1405 extra.data.fields_hash_3,1395 extra.data.fields_hash_3,
1406 });1396 });
14071397
1408 try stream.print("hash({}) ", .{std.fmt.fmtSliceHexLower(&fields_hash)});1398 try stream.print("hash({x}) ", .{&fields_hash});
14091399
1410 var extra_index: usize = extra.end;1400 var extra_index: usize = extra.end;
14111401
...@@ -1463,7 +1453,7 @@ const Writer = struct {...@@ -1463,7 +1453,7 @@ const Writer = struct {
1463 try self.writeBody(stream, self.code.bodySlice(extra_index, decls_len));1453 try self.writeBody(stream, self.code.bodySlice(extra_index, decls_len));
1464 self.indent -= 2;1454 self.indent -= 2;
1465 extra_index += decls_len;1455 extra_index += decls_len;
1466 try stream.writeByteNTimes(' ', self.indent);1456 try stream.splatByteAll(' ', self.indent);
1467 try stream.writeAll("}, ");1457 try stream.writeAll("}, ");
1468 }1458 }
14691459
...@@ -1532,7 +1522,7 @@ const Writer = struct {...@@ -1532,7 +1522,7 @@ const Writer = struct {
1532 self.indent += 2;1522 self.indent += 2;
15331523
1534 for (fields, 0..) |field, i| {1524 for (fields, 0..) |field, i| {
1535 try stream.writeByteNTimes(' ', self.indent);1525 try stream.splatByteAll(' ', self.indent);
1536 try self.writeFlag(stream, "comptime ", field.is_comptime);1526 try self.writeFlag(stream, "comptime ", field.is_comptime);
1537 if (field.name != .empty) {1527 if (field.name != .empty) {
1538 const field_name = self.code.nullTerminatedString(field.name);1528 const field_name = self.code.nullTerminatedString(field.name);
...@@ -1575,13 +1565,13 @@ const Writer = struct {...@@ -1575,13 +1565,13 @@ const Writer = struct {
1575 }1565 }
15761566
1577 self.indent -= 2;1567 self.indent -= 2;
1578 try stream.writeByteNTimes(' ', self.indent);1568 try stream.splatByteAll(' ', self.indent);
1579 try stream.writeAll("}) ");1569 try stream.writeAll("}) ");
1580 }1570 }
1581 try self.writeSrcNode(stream, .zero);1571 try self.writeSrcNode(stream, .zero);
1582 }1572 }
15831573
1584 fn writeUnionDecl(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {1574 fn writeUnionDecl(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void {
1585 const small = @as(Zir.Inst.UnionDecl.Small, @bitCast(extended.small));1575 const small = @as(Zir.Inst.UnionDecl.Small, @bitCast(extended.small));
15861576
1587 const extra = self.code.extraData(Zir.Inst.UnionDecl, extended.operand);1577 const extra = self.code.extraData(Zir.Inst.UnionDecl, extended.operand);
...@@ -1597,7 +1587,7 @@ const Writer = struct {...@@ -1597,7 +1587,7 @@ const Writer = struct {
1597 extra.data.fields_hash_3,1587 extra.data.fields_hash_3,
1598 });1588 });
15991589
1600 try stream.print("hash({}) ", .{std.fmt.fmtSliceHexLower(&fields_hash)});1590 try stream.print("hash({x}) ", .{&fields_hash});
16011591
1602 var extra_index: usize = extra.end;1592 var extra_index: usize = extra.end;
16031593
...@@ -1647,7 +1637,7 @@ const Writer = struct {...@@ -1647,7 +1637,7 @@ const Writer = struct {
1647 try self.writeBody(stream, self.code.bodySlice(extra_index, decls_len));1637 try self.writeBody(stream, self.code.bodySlice(extra_index, decls_len));
1648 self.indent -= 2;1638 self.indent -= 2;
1649 extra_index += decls_len;1639 extra_index += decls_len;
1650 try stream.writeByteNTimes(' ', self.indent);1640 try stream.splatByteAll(' ', self.indent);
1651 try stream.writeAll("}");1641 try stream.writeAll("}");
1652 }1642 }
16531643
...@@ -1698,7 +1688,7 @@ const Writer = struct {...@@ -1698,7 +1688,7 @@ const Writer = struct {
1698 const field_name = self.code.nullTerminatedString(field_name_index);1688 const field_name = self.code.nullTerminatedString(field_name_index);
1699 extra_index += 1;1689 extra_index += 1;
17001690
1701 try stream.writeByteNTimes(' ', self.indent);1691 try stream.splatByteAll(' ', self.indent);
1702 try stream.print("{p}", .{std.zig.fmtId(field_name)});1692 try stream.print("{p}", .{std.zig.fmtId(field_name)});
17031693
1704 if (has_type) {1694 if (has_type) {
...@@ -1727,12 +1717,12 @@ const Writer = struct {...@@ -1727,12 +1717,12 @@ const Writer = struct {
1727 }1717 }
17281718
1729 self.indent -= 2;1719 self.indent -= 2;
1730 try stream.writeByteNTimes(' ', self.indent);1720 try stream.splatByteAll(' ', self.indent);
1731 try stream.writeAll("}) ");1721 try stream.writeAll("}) ");
1732 try self.writeSrcNode(stream, .zero);1722 try self.writeSrcNode(stream, .zero);
1733 }1723 }
17341724
1735 fn writeEnumDecl(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {1725 fn writeEnumDecl(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void {
1736 const small = @as(Zir.Inst.EnumDecl.Small, @bitCast(extended.small));1726 const small = @as(Zir.Inst.EnumDecl.Small, @bitCast(extended.small));
17371727
1738 const extra = self.code.extraData(Zir.Inst.EnumDecl, extended.operand);1728 const extra = self.code.extraData(Zir.Inst.EnumDecl, extended.operand);
...@@ -1748,7 +1738,7 @@ const Writer = struct {...@@ -1748,7 +1738,7 @@ const Writer = struct {
1748 extra.data.fields_hash_3,1738 extra.data.fields_hash_3,
1749 });1739 });
17501740
1751 try stream.print("hash({}) ", .{std.fmt.fmtSliceHexLower(&fields_hash)});1741 try stream.print("hash({x}) ", .{&fields_hash});
17521742
1753 var extra_index: usize = extra.end;1743 var extra_index: usize = extra.end;
17541744
...@@ -1796,7 +1786,7 @@ const Writer = struct {...@@ -1796,7 +1786,7 @@ const Writer = struct {
1796 try self.writeBody(stream, self.code.bodySlice(extra_index, decls_len));1786 try self.writeBody(stream, self.code.bodySlice(extra_index, decls_len));
1797 self.indent -= 2;1787 self.indent -= 2;
1798 extra_index += decls_len;1788 extra_index += decls_len;
1799 try stream.writeByteNTimes(' ', self.indent);1789 try stream.splatByteAll(' ', self.indent);
1800 try stream.writeAll("}, ");1790 try stream.writeAll("}, ");
1801 }1791 }
18021792
...@@ -1832,7 +1822,7 @@ const Writer = struct {...@@ -1832,7 +1822,7 @@ const Writer = struct {
1832 const field_name = self.code.nullTerminatedString(@enumFromInt(self.code.extra[extra_index]));1822 const field_name = self.code.nullTerminatedString(@enumFromInt(self.code.extra[extra_index]));
1833 extra_index += 1;1823 extra_index += 1;
18341824
1835 try stream.writeByteNTimes(' ', self.indent);1825 try stream.splatByteAll(' ', self.indent);
1836 try stream.print("{p}", .{std.zig.fmtId(field_name)});1826 try stream.print("{p}", .{std.zig.fmtId(field_name)});
18371827
1838 if (has_tag_value) {1828 if (has_tag_value) {
...@@ -1845,7 +1835,7 @@ const Writer = struct {...@@ -1845,7 +1835,7 @@ const Writer = struct {
1845 try stream.writeAll(",\n");1835 try stream.writeAll(",\n");
1846 }1836 }
1847 self.indent -= 2;1837 self.indent -= 2;
1848 try stream.writeByteNTimes(' ', self.indent);1838 try stream.splatByteAll(' ', self.indent);
1849 try stream.writeAll("}) ");1839 try stream.writeAll("}) ");
1850 }1840 }
1851 try self.writeSrcNode(stream, .zero);1841 try self.writeSrcNode(stream, .zero);
...@@ -1853,7 +1843,7 @@ const Writer = struct {...@@ -1853,7 +1843,7 @@ const Writer = struct {
18531843
1854 fn writeOpaqueDecl(1844 fn writeOpaqueDecl(
1855 self: *Writer,1845 self: *Writer,
1856 stream: anytype,1846 stream: *std.io.BufferedWriter,
1857 extended: Zir.Inst.Extended.InstData,1847 extended: Zir.Inst.Extended.InstData,
1858 ) !void {1848 ) !void {
1859 const small = @as(Zir.Inst.OpaqueDecl.Small, @bitCast(extended.small));1849 const small = @as(Zir.Inst.OpaqueDecl.Small, @bitCast(extended.small));
...@@ -1889,13 +1879,13 @@ const Writer = struct {...@@ -1889,13 +1879,13 @@ const Writer = struct {
1889 self.indent += 2;1879 self.indent += 2;
1890 try self.writeBody(stream, self.code.bodySlice(extra_index, decls_len));1880 try self.writeBody(stream, self.code.bodySlice(extra_index, decls_len));
1891 self.indent -= 2;1881 self.indent -= 2;
1892 try stream.writeByteNTimes(' ', self.indent);1882 try stream.splatByteAll(' ', self.indent);
1893 try stream.writeAll("}) ");1883 try stream.writeAll("}) ");
1894 }1884 }
1895 try self.writeSrcNode(stream, .zero);1885 try self.writeSrcNode(stream, .zero);
1896 }1886 }
18971887
1898 fn writeTupleDecl(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {1888 fn writeTupleDecl(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void {
1899 const fields_len = extended.small;1889 const fields_len = extended.small;
1900 assert(fields_len != 0);1890 assert(fields_len != 0);
1901 const extra = self.code.extraData(Zir.Inst.TupleDecl, extended.operand);1891 const extra = self.code.extraData(Zir.Inst.TupleDecl, extended.operand);
...@@ -1923,7 +1913,7 @@ const Writer = struct {...@@ -1923,7 +1913,7 @@ const Writer = struct {
19231913
1924 fn writeErrorSetDecl(1914 fn writeErrorSetDecl(
1925 self: *Writer,1915 self: *Writer,
1926 stream: anytype,1916 stream: *std.io.BufferedWriter,
1927 inst: Zir.Inst.Index,1917 inst: Zir.Inst.Index,
1928 ) !void {1918 ) !void {
1929 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;1919 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
...@@ -1937,18 +1927,18 @@ const Writer = struct {...@@ -1937,18 +1927,18 @@ const Writer = struct {
1937 while (extra_index < extra_index_end) : (extra_index += 1) {1927 while (extra_index < extra_index_end) : (extra_index += 1) {
1938 const name_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);1928 const name_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);
1939 const name = self.code.nullTerminatedString(name_index);1929 const name = self.code.nullTerminatedString(name_index);
1940 try stream.writeByteNTimes(' ', self.indent);1930 try stream.splatByteAll(' ', self.indent);
1941 try stream.print("{p},\n", .{std.zig.fmtId(name)});1931 try stream.print("{p},\n", .{std.zig.fmtId(name)});
1942 }1932 }
19431933
1944 self.indent -= 2;1934 self.indent -= 2;
1945 try stream.writeByteNTimes(' ', self.indent);1935 try stream.splatByteAll(' ', self.indent);
1946 try stream.writeAll("}) ");1936 try stream.writeAll("}) ");
19471937
1948 try self.writeSrcNode(stream, inst_data.src_node);1938 try self.writeSrcNode(stream, inst_data.src_node);
1949 }1939 }
19501940
1951 fn writeSwitchBlockErrUnion(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {1941 fn writeSwitchBlockErrUnion(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
1952 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;1942 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
1953 const extra = self.code.extraData(Zir.Inst.SwitchBlockErrUnion, inst_data.payload_index);1943 const extra = self.code.extraData(Zir.Inst.SwitchBlockErrUnion, inst_data.payload_index);
19541944
...@@ -1984,7 +1974,7 @@ const Writer = struct {...@@ -1984,7 +1974,7 @@ const Writer = struct {
1984 extra_index += body.len;1974 extra_index += body.len;
19851975
1986 try stream.writeAll(",\n");1976 try stream.writeAll(",\n");
1987 try stream.writeByteNTimes(' ', self.indent);1977 try stream.splatByteAll(' ', self.indent);
1988 try stream.writeAll("non_err => ");1978 try stream.writeAll("non_err => ");
1989 try self.writeBracedBody(stream, body);1979 try self.writeBracedBody(stream, body);
1990 }1980 }
...@@ -2002,7 +1992,7 @@ const Writer = struct {...@@ -2002,7 +1992,7 @@ const Writer = struct {
2002 extra_index += body.len;1992 extra_index += body.len;
20031993
2004 try stream.writeAll(",\n");1994 try stream.writeAll(",\n");
2005 try stream.writeByteNTimes(' ', self.indent);1995 try stream.splatByteAll(' ', self.indent);
2006 try stream.print("{s}{s}else => ", .{ capture_text, inline_text });1996 try stream.print("{s}{s}else => ", .{ capture_text, inline_text });
2007 try self.writeBracedBody(stream, body);1997 try self.writeBracedBody(stream, body);
2008 }1998 }
...@@ -2019,7 +2009,7 @@ const Writer = struct {...@@ -2019,7 +2009,7 @@ const Writer = struct {
2019 extra_index += info.body_len;2009 extra_index += info.body_len;
20202010
2021 try stream.writeAll(",\n");2011 try stream.writeAll(",\n");
2022 try stream.writeByteNTimes(' ', self.indent);2012 try stream.splatByteAll(' ', self.indent);
2023 switch (info.capture) {2013 switch (info.capture) {
2024 .none => {},2014 .none => {},
2025 .by_val => try stream.writeAll("by_val "),2015 .by_val => try stream.writeAll("by_val "),
...@@ -2044,7 +2034,7 @@ const Writer = struct {...@@ -2044,7 +2034,7 @@ const Writer = struct {
2044 extra_index += items_len;2034 extra_index += items_len;
20452035
2046 try stream.writeAll(",\n");2036 try stream.writeAll(",\n");
2047 try stream.writeByteNTimes(' ', self.indent);2037 try stream.splatByteAll(' ', self.indent);
2048 switch (info.capture) {2038 switch (info.capture) {
2049 .none => {},2039 .none => {},
2050 .by_val => try stream.writeAll("by_val "),2040 .by_val => try stream.writeAll("by_val "),
...@@ -2085,7 +2075,7 @@ const Writer = struct {...@@ -2085,7 +2075,7 @@ const Writer = struct {
2085 try self.writeSrcNode(stream, inst_data.src_node);2075 try self.writeSrcNode(stream, inst_data.src_node);
2086 }2076 }
20872077
2088 fn writeSwitchBlock(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {2078 fn writeSwitchBlock(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
2089 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;2079 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
2090 const extra = self.code.extraData(Zir.Inst.SwitchBlock, inst_data.payload_index);2080 const extra = self.code.extraData(Zir.Inst.SwitchBlock, inst_data.payload_index);
20912081
...@@ -2132,7 +2122,7 @@ const Writer = struct {...@@ -2132,7 +2122,7 @@ const Writer = struct {
2132 extra_index += body.len;2122 extra_index += body.len;
21332123
2134 try stream.writeAll(",\n");2124 try stream.writeAll(",\n");
2135 try stream.writeByteNTimes(' ', self.indent);2125 try stream.splatByteAll(' ', self.indent);
2136 try stream.print("{s}{s}{s} => ", .{ capture_text, inline_text, prong_name });2126 try stream.print("{s}{s}{s} => ", .{ capture_text, inline_text, prong_name });
2137 try self.writeBracedBody(stream, body);2127 try self.writeBracedBody(stream, body);
2138 }2128 }
...@@ -2149,7 +2139,7 @@ const Writer = struct {...@@ -2149,7 +2139,7 @@ const Writer = struct {
2149 extra_index += info.body_len;2139 extra_index += info.body_len;
21502140
2151 try stream.writeAll(",\n");2141 try stream.writeAll(",\n");
2152 try stream.writeByteNTimes(' ', self.indent);2142 try stream.splatByteAll(' ', self.indent);
2153 switch (info.capture) {2143 switch (info.capture) {
2154 .none => {},2144 .none => {},
2155 .by_val => try stream.writeAll("by_val "),2145 .by_val => try stream.writeAll("by_val "),
...@@ -2174,7 +2164,7 @@ const Writer = struct {...@@ -2174,7 +2164,7 @@ const Writer = struct {
2174 extra_index += items_len;2164 extra_index += items_len;
21752165
2176 try stream.writeAll(",\n");2166 try stream.writeAll(",\n");
2177 try stream.writeByteNTimes(' ', self.indent);2167 try stream.splatByteAll(' ', self.indent);
2178 switch (info.capture) {2168 switch (info.capture) {
2179 .none => {},2169 .none => {},
2180 .by_val => try stream.writeAll("by_val "),2170 .by_val => try stream.writeAll("by_val "),
...@@ -2215,7 +2205,7 @@ const Writer = struct {...@@ -2215,7 +2205,7 @@ const Writer = struct {
2215 try self.writeSrcNode(stream, inst_data.src_node);2205 try self.writeSrcNode(stream, inst_data.src_node);
2216 }2206 }
22172207
2218 fn writePlNodeField(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {2208 fn writePlNodeField(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
2219 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;2209 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
2220 const extra = self.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;2210 const extra = self.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;
2221 const name = self.code.nullTerminatedString(extra.field_name_start);2211 const name = self.code.nullTerminatedString(extra.field_name_start);
...@@ -2224,7 +2214,7 @@ const Writer = struct {...@@ -2224,7 +2214,7 @@ const Writer = struct {
2224 try self.writeSrcNode(stream, inst_data.src_node);2214 try self.writeSrcNode(stream, inst_data.src_node);
2225 }2215 }
22262216
2227 fn writePlNodeFieldNamed(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {2217 fn writePlNodeFieldNamed(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
2228 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;2218 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
2229 const extra = self.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;2219 const extra = self.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;
2230 try self.writeInstRef(stream, extra.lhs);2220 try self.writeInstRef(stream, extra.lhs);
...@@ -2234,7 +2224,7 @@ const Writer = struct {...@@ -2234,7 +2224,7 @@ const Writer = struct {
2234 try self.writeSrcNode(stream, inst_data.src_node);2224 try self.writeSrcNode(stream, inst_data.src_node);
2235 }2225 }
22362226
2237 fn writeAs(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {2227 fn writeAs(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
2238 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;2228 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
2239 const extra = self.code.extraData(Zir.Inst.As, inst_data.payload_index).data;2229 const extra = self.code.extraData(Zir.Inst.As, inst_data.payload_index).data;
2240 try self.writeInstRef(stream, extra.dest_type);2230 try self.writeInstRef(stream, extra.dest_type);
...@@ -2246,9 +2236,9 @@ const Writer = struct {...@@ -2246,9 +2236,9 @@ const Writer = struct {
22462236
2247 fn writeNode(2237 fn writeNode(
2248 self: *Writer,2238 self: *Writer,
2249 stream: anytype,2239 stream: *std.io.BufferedWriter,
2250 inst: Zir.Inst.Index,2240 inst: Zir.Inst.Index,
2251 ) (@TypeOf(stream).Error || error{OutOfMemory})!void {2241 ) anyerror!void {
2252 const src_node = self.code.instructions.items(.data)[@intFromEnum(inst)].node;2242 const src_node = self.code.instructions.items(.data)[@intFromEnum(inst)].node;
2253 try stream.writeAll(") ");2243 try stream.writeAll(") ");
2254 try self.writeSrcNode(stream, src_node);2244 try self.writeSrcNode(stream, src_node);
...@@ -2256,16 +2246,16 @@ const Writer = struct {...@@ -2256,16 +2246,16 @@ const Writer = struct {
22562246
2257 fn writeStrTok(2247 fn writeStrTok(
2258 self: *Writer,2248 self: *Writer,
2259 stream: anytype,2249 stream: *std.io.BufferedWriter,
2260 inst: Zir.Inst.Index,2250 inst: Zir.Inst.Index,
2261 ) (@TypeOf(stream).Error || error{OutOfMemory})!void {2251 ) anyerror!void {
2262 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;2252 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
2263 const str = inst_data.get(self.code);2253 const str = inst_data.get(self.code);
2264 try stream.print("\"{}\") ", .{std.zig.fmtEscapes(str)});2254 try stream.print("\"{}\") ", .{std.zig.fmtEscapes(str)});
2265 try self.writeSrcTok(stream, inst_data.src_tok);2255 try self.writeSrcTok(stream, inst_data.src_tok);
2266 }2256 }
22672257
2268 fn writeStrOp(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {2258 fn writeStrOp(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
2269 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str_op;2259 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str_op;
2270 const str = inst_data.getStr(self.code);2260 const str = inst_data.getStr(self.code);
2271 try self.writeInstRef(stream, inst_data.operand);2261 try self.writeInstRef(stream, inst_data.operand);
...@@ -2274,7 +2264,7 @@ const Writer = struct {...@@ -2274,7 +2264,7 @@ const Writer = struct {
22742264
2275 fn writeFunc(2265 fn writeFunc(
2276 self: *Writer,2266 self: *Writer,
2277 stream: anytype,2267 stream: *std.io.BufferedWriter,
2278 inst: Zir.Inst.Index,2268 inst: Zir.Inst.Index,
2279 inferred_error_set: bool,2269 inferred_error_set: bool,
2280 ) !void {2270 ) !void {
...@@ -2325,7 +2315,7 @@ const Writer = struct {...@@ -2325,7 +2315,7 @@ const Writer = struct {
2325 );2315 );
2326 }2316 }
23272317
2328 fn writeFuncFancy(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {2318 fn writeFuncFancy(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
2329 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;2319 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
2330 const extra = self.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index);2320 const extra = self.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index);
23312321
...@@ -2384,7 +2374,7 @@ const Writer = struct {...@@ -2384,7 +2374,7 @@ const Writer = struct {
2384 );2374 );
2385 }2375 }
23862376
2387 fn writeAllocExtended(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {2377 fn writeAllocExtended(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void {
2388 const extra = self.code.extraData(Zir.Inst.AllocExtended, extended.operand);2378 const extra = self.code.extraData(Zir.Inst.AllocExtended, extended.operand);
2389 const small = @as(Zir.Inst.AllocExtended.Small, @bitCast(extended.small));2379 const small = @as(Zir.Inst.AllocExtended.Small, @bitCast(extended.small));
23902380
...@@ -2407,7 +2397,7 @@ const Writer = struct {...@@ -2407,7 +2397,7 @@ const Writer = struct {
2407 try self.writeSrcNode(stream, extra.data.src_node);2397 try self.writeSrcNode(stream, extra.data.src_node);
2408 }2398 }
24092399
2410 fn writeTypeofPeer(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {2400 fn writeTypeofPeer(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void {
2411 const extra = self.code.extraData(Zir.Inst.TypeOfPeer, extended.operand);2401 const extra = self.code.extraData(Zir.Inst.TypeOfPeer, extended.operand);
2412 const body = self.code.bodySlice(extra.data.body_index, extra.data.body_len);2402 const body = self.code.bodySlice(extra.data.body_index, extra.data.body_len);
2413 try self.writeBracedBody(stream, body);2403 try self.writeBracedBody(stream, body);
...@@ -2420,7 +2410,7 @@ const Writer = struct {...@@ -2420,7 +2410,7 @@ const Writer = struct {
2420 try stream.writeAll("])");2410 try stream.writeAll("])");
2421 }2411 }
24222412
2423 fn writeBoolBr(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {2413 fn writeBoolBr(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
2424 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;2414 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
2425 const extra = self.code.extraData(Zir.Inst.BoolBr, inst_data.payload_index);2415 const extra = self.code.extraData(Zir.Inst.BoolBr, inst_data.payload_index);
2426 const body = self.code.bodySlice(extra.end, extra.data.body_len);2416 const body = self.code.bodySlice(extra.end, extra.data.body_len);
...@@ -2431,7 +2421,7 @@ const Writer = struct {...@@ -2431,7 +2421,7 @@ const Writer = struct {
2431 try self.writeSrcNode(stream, inst_data.src_node);2421 try self.writeSrcNode(stream, inst_data.src_node);
2432 }2422 }
24332423
2434 fn writeIntType(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {2424 fn writeIntType(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
2435 const int_type = self.code.instructions.items(.data)[@intFromEnum(inst)].int_type;2425 const int_type = self.code.instructions.items(.data)[@intFromEnum(inst)].int_type;
2436 const prefix: u8 = switch (int_type.signedness) {2426 const prefix: u8 = switch (int_type.signedness) {
2437 .signed => 'i',2427 .signed => 'i',
...@@ -2441,7 +2431,7 @@ const Writer = struct {...@@ -2441,7 +2431,7 @@ const Writer = struct {
2441 try self.writeSrcNode(stream, int_type.src_node);2431 try self.writeSrcNode(stream, int_type.src_node);
2442 }2432 }
24432433
2444 fn writeSaveErrRetIndex(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {2434 fn writeSaveErrRetIndex(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
2445 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].save_err_ret_index;2435 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].save_err_ret_index;
24462436
2447 try self.writeInstRef(stream, inst_data.operand);2437 try self.writeInstRef(stream, inst_data.operand);
...@@ -2449,7 +2439,7 @@ const Writer = struct {...@@ -2449,7 +2439,7 @@ const Writer = struct {
2449 try stream.writeAll(")");2439 try stream.writeAll(")");
2450 }2440 }
24512441
2452 fn writeRestoreErrRetIndex(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {2442 fn writeRestoreErrRetIndex(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void {
2453 const extra = self.code.extraData(Zir.Inst.RestoreErrRetIndex, extended.operand).data;2443 const extra = self.code.extraData(Zir.Inst.RestoreErrRetIndex, extended.operand).data;
24542444
2455 try self.writeInstRef(stream, extra.block);2445 try self.writeInstRef(stream, extra.block);
...@@ -2459,7 +2449,7 @@ const Writer = struct {...@@ -2459,7 +2449,7 @@ const Writer = struct {
2459 try self.writeSrcNode(stream, extra.src_node);2449 try self.writeSrcNode(stream, extra.src_node);
2460 }2450 }
24612451
2462 fn writeBreak(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {2452 fn writeBreak(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
2463 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].@"break";2453 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].@"break";
2464 const extra = self.code.extraData(Zir.Inst.Break, inst_data.payload_index).data;2454 const extra = self.code.extraData(Zir.Inst.Break, inst_data.payload_index).data;
24652455
...@@ -2469,7 +2459,7 @@ const Writer = struct {...@@ -2469,7 +2459,7 @@ const Writer = struct {
2469 try stream.writeAll(")");2459 try stream.writeAll(")");
2470 }2460 }
24712461
2472 fn writeArrayInit(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {2462 fn writeArrayInit(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
2473 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;2463 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
24742464
2475 const extra = self.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);2465 const extra = self.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);
...@@ -2485,7 +2475,7 @@ const Writer = struct {...@@ -2485,7 +2475,7 @@ const Writer = struct {
2485 try self.writeSrcNode(stream, inst_data.src_node);2475 try self.writeSrcNode(stream, inst_data.src_node);
2486 }2476 }
24872477
2488 fn writeArrayInitAnon(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {2478 fn writeArrayInitAnon(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
2489 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;2479 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
24902480
2491 const extra = self.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);2481 const extra = self.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);
...@@ -2500,7 +2490,7 @@ const Writer = struct {...@@ -2500,7 +2490,7 @@ const Writer = struct {
2500 try self.writeSrcNode(stream, inst_data.src_node);2490 try self.writeSrcNode(stream, inst_data.src_node);
2501 }2491 }
25022492
2503 fn writeArrayInitSent(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {2493 fn writeArrayInitSent(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
2504 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;2494 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
25052495
2506 const extra = self.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);2496 const extra = self.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);
...@@ -2520,7 +2510,7 @@ const Writer = struct {...@@ -2520,7 +2510,7 @@ const Writer = struct {
2520 try self.writeSrcNode(stream, inst_data.src_node);2510 try self.writeSrcNode(stream, inst_data.src_node);
2521 }2511 }
25222512
2523 fn writeUnreachable(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {2513 fn writeUnreachable(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
2524 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].@"unreachable";2514 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].@"unreachable";
2525 try stream.writeAll(") ");2515 try stream.writeAll(") ");
2526 try self.writeSrcNode(stream, inst_data.src_node);2516 try self.writeSrcNode(stream, inst_data.src_node);
...@@ -2528,7 +2518,7 @@ const Writer = struct {...@@ -2528,7 +2518,7 @@ const Writer = struct {
25282518
2529 fn writeFuncCommon(2519 fn writeFuncCommon(
2530 self: *Writer,2520 self: *Writer,
2531 stream: anytype,2521 stream: *std.io.BufferedWriter,
2532 inferred_error_set: bool,2522 inferred_error_set: bool,
2533 var_args: bool,2523 var_args: bool,
2534 is_noinline: bool,2524 is_noinline: bool,
...@@ -2565,19 +2555,19 @@ const Writer = struct {...@@ -2565,19 +2555,19 @@ const Writer = struct {
2565 try self.writeSrcNode(stream, src_node);2555 try self.writeSrcNode(stream, src_node);
2566 }2556 }
25672557
2568 fn writeDbgStmt(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {2558 fn writeDbgStmt(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
2569 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;2559 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
2570 try stream.print("{d}, {d})", .{ inst_data.line + 1, inst_data.column + 1 });2560 try stream.print("{d}, {d})", .{ inst_data.line + 1, inst_data.column + 1 });
2571 }2561 }
25722562
2573 fn writeDefer(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {2563 fn writeDefer(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
2574 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].@"defer";2564 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].@"defer";
2575 const body = self.code.bodySlice(inst_data.index, inst_data.len);2565 const body = self.code.bodySlice(inst_data.index, inst_data.len);
2576 try self.writeBracedBody(stream, body);2566 try self.writeBracedBody(stream, body);
2577 try stream.writeByte(')');2567 try stream.writeByte(')');
2578 }2568 }
25792569
2580 fn writeDeferErrCode(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {2570 fn writeDeferErrCode(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
2581 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].defer_err_code;2571 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].defer_err_code;
2582 const extra = self.code.extraData(Zir.Inst.DeferErrCode, inst_data.payload_index).data;2572 const extra = self.code.extraData(Zir.Inst.DeferErrCode, inst_data.payload_index).data;
25832573
...@@ -2590,7 +2580,7 @@ const Writer = struct {...@@ -2590,7 +2580,7 @@ const Writer = struct {
2590 try stream.writeByte(')');2580 try stream.writeByte(')');
2591 }2581 }
25922582
2593 fn writeDeclaration(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {2583 fn writeDeclaration(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
2594 const decl = self.code.getDeclaration(inst);2584 const decl = self.code.getDeclaration(inst);
25952585
2596 const prev_parent_decl_node = self.parent_decl_node;2586 const prev_parent_decl_node = self.parent_decl_node;
...@@ -2612,10 +2602,8 @@ const Writer = struct {...@@ -2612,10 +2602,8 @@ const Writer = struct {
2612 },2602 },
2613 }2603 }
2614 const src_hash = self.code.getAssociatedSrcHash(inst).?;2604 const src_hash = self.code.getAssociatedSrcHash(inst).?;
2615 try stream.print(" line({d}) column({d}) hash({})", .{2605 try stream.print(" line({d}) column({d}) hash({x})", .{
2616 decl.src_line,2606 decl.src_line, decl.src_column, &src_hash,
2617 decl.src_column,
2618 std.fmt.fmtSliceHexLower(&src_hash),
2619 });2607 });
26202608
2621 {2609 {
...@@ -2649,26 +2637,26 @@ const Writer = struct {...@@ -2649,26 +2637,26 @@ const Writer = struct {
2649 try self.writeSrcNode(stream, .zero);2637 try self.writeSrcNode(stream, .zero);
2650 }2638 }
26512639
2652 fn writeClosureGet(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {2640 fn writeClosureGet(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void {
2653 try stream.print("{d})) ", .{extended.small});2641 try stream.print("{d})) ", .{extended.small});
2654 const src_node: Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand)));2642 const src_node: Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand)));
2655 try self.writeSrcNode(stream, src_node);2643 try self.writeSrcNode(stream, src_node);
2656 }2644 }
26572645
2658 fn writeBuiltinValue(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {2646 fn writeBuiltinValue(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void {
2659 const val: Zir.Inst.BuiltinValue = @enumFromInt(extended.small);2647 const val: Zir.Inst.BuiltinValue = @enumFromInt(extended.small);
2660 try stream.print("{s})) ", .{@tagName(val)});2648 try stream.print("{s})) ", .{@tagName(val)});
2661 const src_node: Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand)));2649 const src_node: Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand)));
2662 try self.writeSrcNode(stream, src_node);2650 try self.writeSrcNode(stream, src_node);
2663 }2651 }
26642652
2665 fn writeInplaceArithResultTy(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {2653 fn writeInplaceArithResultTy(self: *Writer, stream: *std.io.BufferedWriter, extended: Zir.Inst.Extended.InstData) !void {
2666 const op: Zir.Inst.InplaceOp = @enumFromInt(extended.small);2654 const op: Zir.Inst.InplaceOp = @enumFromInt(extended.small);
2667 try self.writeInstRef(stream, @enumFromInt(extended.operand));2655 try self.writeInstRef(stream, @enumFromInt(extended.operand));
2668 try stream.print(", {s}))", .{@tagName(op)});2656 try stream.print(", {s}))", .{@tagName(op)});
2669 }2657 }
26702658
2671 fn writeInstRef(self: *Writer, stream: anytype, ref: Zir.Inst.Ref) !void {2659 fn writeInstRef(self: *Writer, stream: *std.io.BufferedWriter, ref: Zir.Inst.Ref) !void {
2672 if (ref == .none) {2660 if (ref == .none) {
2673 return stream.writeAll(".none");2661 return stream.writeAll(".none");
2674 } else if (ref.toIndex()) |i| {2662 } else if (ref.toIndex()) |i| {
...@@ -2679,12 +2667,12 @@ const Writer = struct {...@@ -2679,12 +2667,12 @@ const Writer = struct {
2679 }2667 }
2680 }2668 }
26812669
2682 fn writeInstIndex(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {2670 fn writeInstIndex(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
2683 _ = self;2671 _ = self;
2684 return stream.print("%{d}", .{@intFromEnum(inst)});2672 return stream.print("%{d}", .{@intFromEnum(inst)});
2685 }2673 }
26862674
2687 fn writeCaptures(self: *Writer, stream: anytype, extra_index: usize, captures_len: u32) !usize {2675 fn writeCaptures(self: *Writer, stream: *std.io.BufferedWriter, extra_index: usize, captures_len: u32) !usize {
2688 if (captures_len == 0) {2676 if (captures_len == 0) {
2689 try stream.writeAll("{}");2677 try stream.writeAll("{}");
2690 return extra_index;2678 return extra_index;
...@@ -2704,7 +2692,7 @@ const Writer = struct {...@@ -2704,7 +2692,7 @@ const Writer = struct {
2704 return extra_index + 2 * captures_len;2692 return extra_index + 2 * captures_len;
2705 }2693 }
27062694
2707 fn writeCapture(self: *Writer, stream: anytype, capture: Zir.Inst.Capture) !void {2695 fn writeCapture(self: *Writer, stream: *std.io.BufferedWriter, capture: Zir.Inst.Capture) !void {
2708 switch (capture.unwrap()) {2696 switch (capture.unwrap()) {
2709 .nested => |i| return stream.print("[{d}]", .{i}),2697 .nested => |i| return stream.print("[{d}]", .{i}),
2710 .instruction => |inst| return self.writeInstIndex(stream, inst),2698 .instruction => |inst| return self.writeInstIndex(stream, inst),
...@@ -2723,7 +2711,7 @@ const Writer = struct {...@@ -2723,7 +2711,7 @@ const Writer = struct {
27232711
2724 fn writeOptionalInstRef(2712 fn writeOptionalInstRef(
2725 self: *Writer,2713 self: *Writer,
2726 stream: anytype,2714 stream: *std.io.BufferedWriter,
2727 prefix: []const u8,2715 prefix: []const u8,
2728 inst: Zir.Inst.Ref,2716 inst: Zir.Inst.Ref,
2729 ) !void {2717 ) !void {
...@@ -2734,7 +2722,7 @@ const Writer = struct {...@@ -2734,7 +2722,7 @@ const Writer = struct {
27342722
2735 fn writeOptionalInstRefOrBody(2723 fn writeOptionalInstRefOrBody(
2736 self: *Writer,2724 self: *Writer,
2737 stream: anytype,2725 stream: *std.io.BufferedWriter,
2738 prefix: []const u8,2726 prefix: []const u8,
2739 ref: Zir.Inst.Ref,2727 ref: Zir.Inst.Ref,
2740 body: []const Zir.Inst.Index,2728 body: []const Zir.Inst.Index,
...@@ -2752,7 +2740,7 @@ const Writer = struct {...@@ -2752,7 +2740,7 @@ const Writer = struct {
27522740
2753 fn writeFlag(2741 fn writeFlag(
2754 self: *Writer,2742 self: *Writer,
2755 stream: anytype,2743 stream: *std.io.BufferedWriter,
2756 name: []const u8,2744 name: []const u8,
2757 flag: bool,2745 flag: bool,
2758 ) !void {2746 ) !void {
...@@ -2761,7 +2749,7 @@ const Writer = struct {...@@ -2761,7 +2749,7 @@ const Writer = struct {
2761 try stream.writeAll(name);2749 try stream.writeAll(name);
2762 }2750 }
27632751
2764 fn writeSrcNode(self: *Writer, stream: anytype, src_node: Ast.Node.Offset) !void {2752 fn writeSrcNode(self: *Writer, stream: *std.io.BufferedWriter, src_node: Ast.Node.Offset) !void {
2765 const tree = self.tree orelse return;2753 const tree = self.tree orelse return;
2766 const abs_node = src_node.toAbsolute(self.parent_decl_node);2754 const abs_node = src_node.toAbsolute(self.parent_decl_node);
2767 const src_span = tree.nodeToSpan(abs_node);2755 const src_span = tree.nodeToSpan(abs_node);
...@@ -2773,7 +2761,7 @@ const Writer = struct {...@@ -2773,7 +2761,7 @@ const Writer = struct {
2773 });2761 });
2774 }2762 }
27752763
2776 fn writeSrcTok(self: *Writer, stream: anytype, src_tok: Ast.TokenOffset) !void {2764 fn writeSrcTok(self: *Writer, stream: *std.io.BufferedWriter, src_tok: Ast.TokenOffset) !void {
2777 const tree = self.tree orelse return;2765 const tree = self.tree orelse return;
2778 const abs_tok = src_tok.toAbsolute(tree.firstToken(self.parent_decl_node));2766 const abs_tok = src_tok.toAbsolute(tree.firstToken(self.parent_decl_node));
2779 const span_start = tree.tokenStart(abs_tok);2767 const span_start = tree.tokenStart(abs_tok);
...@@ -2786,7 +2774,7 @@ const Writer = struct {...@@ -2786,7 +2774,7 @@ const Writer = struct {
2786 });2774 });
2787 }2775 }
27882776
2789 fn writeSrcTokAbs(self: *Writer, stream: anytype, src_tok: Ast.TokenIndex) !void {2777 fn writeSrcTokAbs(self: *Writer, stream: *std.io.BufferedWriter, src_tok: Ast.TokenIndex) !void {
2790 const tree = self.tree orelse return;2778 const tree = self.tree orelse return;
2791 const span_start = tree.tokenStart(src_tok);2779 const span_start = tree.tokenStart(src_tok);
2792 const span_end = span_start + @as(u32, @intCast(tree.tokenSlice(src_tok).len));2780 const span_end = span_start + @as(u32, @intCast(tree.tokenSlice(src_tok).len));
...@@ -2798,15 +2786,15 @@ const Writer = struct {...@@ -2798,15 +2786,15 @@ const Writer = struct {
2798 });2786 });
2799 }2787 }
28002788
2801 fn writeBracedDecl(self: *Writer, stream: anytype, body: []const Zir.Inst.Index) !void {2789 fn writeBracedDecl(self: *Writer, stream: *std.io.BufferedWriter, body: []const Zir.Inst.Index) !void {
2802 try self.writeBracedBodyConditional(stream, body, self.recurse_decls);2790 try self.writeBracedBodyConditional(stream, body, self.recurse_decls);
2803 }2791 }
28042792
2805 fn writeBracedBody(self: *Writer, stream: anytype, body: []const Zir.Inst.Index) !void {2793 fn writeBracedBody(self: *Writer, stream: *std.io.BufferedWriter, body: []const Zir.Inst.Index) !void {
2806 try self.writeBracedBodyConditional(stream, body, self.recurse_blocks);2794 try self.writeBracedBodyConditional(stream, body, self.recurse_blocks);
2807 }2795 }
28082796
2809 fn writeBracedBodyConditional(self: *Writer, stream: anytype, body: []const Zir.Inst.Index, enabled: bool) !void {2797 fn writeBracedBodyConditional(self: *Writer, stream: *std.io.BufferedWriter, body: []const Zir.Inst.Index, enabled: bool) !void {
2810 if (body.len == 0) {2798 if (body.len == 0) {
2811 try stream.writeAll("{}");2799 try stream.writeAll("{}");
2812 } else if (enabled) {2800 } else if (enabled) {
...@@ -2814,7 +2802,7 @@ const Writer = struct {...@@ -2814,7 +2802,7 @@ const Writer = struct {
2814 self.indent += 2;2802 self.indent += 2;
2815 try self.writeBody(stream, body);2803 try self.writeBody(stream, body);
2816 self.indent -= 2;2804 self.indent -= 2;
2817 try stream.writeByteNTimes(' ', self.indent);2805 try stream.splatByteAll(' ', self.indent);
2818 try stream.writeAll("}");2806 try stream.writeAll("}");
2819 } else if (body.len == 1) {2807 } else if (body.len == 1) {
2820 try stream.writeByte('{');2808 try stream.writeByte('{');
...@@ -2835,16 +2823,16 @@ const Writer = struct {...@@ -2835,16 +2823,16 @@ const Writer = struct {
2835 }2823 }
2836 }2824 }
28372825
2838 fn writeBody(self: *Writer, stream: anytype, body: []const Zir.Inst.Index) !void {2826 fn writeBody(self: *Writer, stream: *std.io.BufferedWriter, body: []const Zir.Inst.Index) !void {
2839 for (body) |inst| {2827 for (body) |inst| {
2840 try stream.writeByteNTimes(' ', self.indent);2828 try stream.splatByteAll(' ', self.indent);
2841 try stream.print("%{d} ", .{@intFromEnum(inst)});2829 try stream.print("%{d} ", .{@intFromEnum(inst)});
2842 try self.writeInstToStream(stream, inst);2830 try self.writeInstToStream(stream, inst);
2843 try stream.writeByte('\n');2831 try stream.writeByte('\n');
2844 }2832 }
2845 }2833 }
28462834
2847 fn writeImport(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {2835 fn writeImport(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
2848 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_tok;2836 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_tok;
2849 const extra = self.code.extraData(Zir.Inst.Import, inst_data.payload_index).data;2837 const extra = self.code.extraData(Zir.Inst.Import, inst_data.payload_index).data;
2850 try self.writeInstRef(stream, extra.res_ty);2838 try self.writeInstRef(stream, extra.res_ty);
src/print_zoir.zig+13-20
...@@ -1,13 +1,6 @@...@@ -1,13 +1,6 @@
1pub fn renderToFile(zoir: Zoir, arena: Allocator, f: std.fs.File) (std.fs.File.WriteError || Allocator.Error)!void {1pub fn renderToWriter(zoir: Zoir, arena: Allocator, w: *std.io.BufferedWriter) anyerror!void {
2 var bw = std.io.bufferedWriter(f.writer());
3 try renderToWriter(zoir, arena, bw.writer());
4 try bw.flush();
5}
6
7pub fn renderToWriter(zoir: Zoir, arena: Allocator, w: anytype) (@TypeOf(w).Error || Allocator.Error)!void {
8 assert(!zoir.hasCompileErrors());2 assert(!zoir.hasCompileErrors());
93
10 const fmtIntSizeBin = std.fmt.fmtIntSizeBin;
11 const bytes_per_node = comptime n: {4 const bytes_per_node = comptime n: {
12 var n: usize = 0;5 var n: usize = 0;
13 for (@typeInfo(Zoir.Node.Repr).@"struct".fields) |f| {6 for (@typeInfo(Zoir.Node.Repr).@"struct".fields) |f| {
...@@ -23,22 +16,22 @@ pub fn renderToWriter(zoir: Zoir, arena: Allocator, w: anytype) (@TypeOf(w).Erro...@@ -23,22 +16,22 @@ pub fn renderToWriter(zoir: Zoir, arena: Allocator, w: anytype) (@TypeOf(w).Erro
2316
24 // zig fmt: off17 // zig fmt: off
25 try w.print(18 try w.print(
26 \\# Nodes: {} ({})19 \\# Nodes: {} ({Bi})
27 \\# Extra Data Items: {} ({})20 \\# Extra Data Items: {} ({Bi})
28 \\# BigInt Limbs: {} ({})21 \\# BigInt Limbs: {} ({Bi})
29 \\# String Table Bytes: {}22 \\# String Table Bytes: {Bi}
30 \\# Total ZON Bytes: {}23 \\# Total ZON Bytes: {Bi}
31 \\24 \\
32 , .{25 , .{
33 zoir.nodes.len, fmtIntSizeBin(node_bytes),26 zoir.nodes.len, node_bytes,
34 zoir.extra.len, fmtIntSizeBin(extra_bytes),27 zoir.extra.len, extra_bytes,
35 zoir.limbs.len, fmtIntSizeBin(limb_bytes),28 zoir.limbs.len, limb_bytes,
36 fmtIntSizeBin(string_bytes),29 string_bytes,
37 fmtIntSizeBin(node_bytes + extra_bytes + limb_bytes + string_bytes),30 node_bytes + extra_bytes + limb_bytes + string_bytes,
38 });31 });
39 // zig fmt: on32 // zig fmt: on
40 var pz: PrintZon = .{33 var pz: PrintZon = .{
41 .w = w.any(),34 .w = w,
42 .arena = arena,35 .arena = arena,
43 .zoir = zoir,36 .zoir = zoir,
44 .indent = 0,37 .indent = 0,
...@@ -48,7 +41,7 @@ pub fn renderToWriter(zoir: Zoir, arena: Allocator, w: anytype) (@TypeOf(w).Erro...@@ -48,7 +41,7 @@ pub fn renderToWriter(zoir: Zoir, arena: Allocator, w: anytype) (@TypeOf(w).Erro
48}41}
4942
50const PrintZon = struct {43const PrintZon = struct {
51 w: std.io.AnyWriter,44 w: *std.io.BufferedWriter,
52 arena: Allocator,45 arena: Allocator,
53 zoir: Zoir,46 zoir: Zoir,
54 indent: u32,47 indent: u32,
src/translate_c.zig+1-1
...@@ -5905,7 +5905,7 @@ fn parseCPrimaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {...@@ -5905,7 +5905,7 @@ fn parseCPrimaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
5905 if (slice[0] != '\'' or slice[1] == '\\' or slice.len == 3) {5905 if (slice[0] != '\'' or slice[1] == '\\' or slice.len == 3) {
5906 return Tag.char_literal.create(c.arena, try escapeUnprintables(c, m));5906 return Tag.char_literal.create(c.arena, try escapeUnprintables(c, m));
5907 } else {5907 } else {
5908 const str = try std.fmt.allocPrint(c.arena, "0x{s}", .{std.fmt.fmtSliceHexLower(slice[1 .. slice.len - 1])});5908 const str = try std.fmt.allocPrint(c.arena, "0x{x}", .{slice[1 .. slice.len - 1]});
5909 return Tag.integer_literal.create(c.arena, str);5909 return Tag.integer_literal.create(c.arena, str);
5910 }5910 }
5911 },5911 },