authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-07 20:07:28-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-06-07 20:07:28-04:00
log6ff7b437ff34e9a416a041c0c0ff8a65bae8daf5
treee8be8a2b2a1fa6524bead911f3607941d005d8ee
parent3cb387338234620e00645417565dc234dc5105c2
parent413577c881963559f7f357bfd90f4ade6d6de20d
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #11813 from Vexu/stage2

`zig2 build test-std` finale

11 files changed, 155 insertions(+), 53 deletions(-)

lib/std/io/bit_reader.zig+3-7
......@@ -87,13 +87,9 @@ pub fn BitReader(endian: std.builtin.Endian, comptime ReaderType: type) type {
8787 //copy bytes until we have enough bits, then leave the rest in bit_buffer
8888 while (out_bits.* < bits) {
8989 const n = bits - out_bits.*;
90 const next_byte = self.forward_reader.readByte() catch |err| {
91 if (err == error.EndOfStream) {
92 return @intCast(U, out_buffer);
93 }
94 //@BUG: See #1810. Not sure if the bug is that I have to do this for some
95 // streams, or that I don't for streams with emtpy errorsets.
96 return @errSetCast(Error, err);
90 const next_byte = self.forward_reader.readByte() catch |err| switch (err) {
91 error.EndOfStream => return @intCast(U, out_buffer),
92 else => |e| return e,
9793 };
9894
9995 switch (endian) {
lib/std/io/stream_source.zig+1
......@@ -114,6 +114,7 @@ test "StreamSource (mutable buffer)" {
114114}
115115
116116test "StreamSource (const buffer)" {
117 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
117118 const buffer: [64]u8 = "Hello, World!".* ++ ([1]u8{0xAA} ** 51);
118119 var source = StreamSource{ .const_buffer = std.io.fixedBufferStream(&buffer) };
119120
lib/std/math/big/rational.zig+2
......@@ -573,6 +573,7 @@ test "big.rational setFloatString" {
573573}
574574
575575test "big.rational toFloat" {
576 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
576577 var a = try Rational.init(testing.allocator);
577578 defer a.deinit();
578579
......@@ -586,6 +587,7 @@ test "big.rational toFloat" {
586587}
587588
588589test "big.rational set/to Float round-trip" {
590 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
589591 var a = try Rational.init(testing.allocator);
590592 defer a.deinit();
591593 var prng = std.rand.DefaultPrng.init(0x5EED);
lib/std/net.zig+8-3
......@@ -1342,7 +1342,8 @@ fn getResolvConf(allocator: mem.Allocator, rc: *ResolvConf) !void {
13421342 };
13431343 defer file.close();
13441344
1345 const stream = std.io.bufferedReader(file.reader()).reader();
1345 var buf_reader = std.io.bufferedReader(file.reader());
1346 const stream = buf_reader.reader();
13461347 var line_buf: [512]u8 = undefined;
13471348 while (stream.readUntilDelimiterOrEof(&line_buf, '\n') catch |err| switch (err) {
13481349 error.StreamTooLong => blk: {
......@@ -1353,7 +1354,10 @@ fn getResolvConf(allocator: mem.Allocator, rc: *ResolvConf) !void {
13531354 },
13541355 else => |e| return e,
13551356 }) |line| {
1356 const no_comment_line = mem.split(u8, line, "#").next().?;
1357 const no_comment_line = no_comment_line: {
1358 var split = mem.split(u8, line, "#");
1359 break :no_comment_line split.next().?;
1360 };
13571361 var line_it = mem.tokenize(u8, no_comment_line, " \t");
13581362
13591363 const token = line_it.next() orelse continue;
......@@ -1363,7 +1367,8 @@ fn getResolvConf(allocator: mem.Allocator, rc: *ResolvConf) !void {
13631367 const name = colon_it.next().?;
13641368 const value_txt = colon_it.next() orelse continue;
13651369 const value = std.fmt.parseInt(u8, value_txt, 10) catch |err| switch (err) {
1366 error.Overflow => 255,
1370 // TODO https://github.com/ziglang/zig/issues/11812
1371 error.Overflow => @as(u8, 255),
13671372 error.InvalidCharacter => continue,
13681373 };
13691374 if (mem.eql(u8, name, "ndots")) {
lib/std/net/test.zig+4
......@@ -5,6 +5,7 @@ const mem = std.mem;
55const testing = std.testing;
66
77test "parse and render IPv6 addresses" {
8 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
89 if (builtin.os.tag == .wasi) return error.SkipZigTest;
910
1011 var buffer: [100]u8 = undefined;
......@@ -67,6 +68,7 @@ test "invalid but parseable IPv6 scope ids" {
6768}
6869
6970test "parse and render IPv4 addresses" {
71 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
7072 if (builtin.os.tag == .wasi) return error.SkipZigTest;
7173
7274 var buffer: [18]u8 = undefined;
......@@ -91,6 +93,7 @@ test "parse and render IPv4 addresses" {
9193}
9294
9395test "parse and render UNIX addresses" {
96 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
9497 if (builtin.os.tag == .wasi) return error.SkipZigTest;
9598 if (!net.has_unix_sockets) return error.SkipZigTest;
9699
......@@ -104,6 +107,7 @@ test "parse and render UNIX addresses" {
104107}
105108
106109test "resolve DNS" {
110 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
107111 if (builtin.os.tag == .wasi) return error.SkipZigTest;
108112
109113 if (builtin.os.tag == .windows) {
lib/std/priority_queue.zig+1
......@@ -399,6 +399,7 @@ test "std.PriorityQueue: fromOwnedSlice trivial case 1" {
399399}
400400
401401test "std.PriorityQueue: fromOwnedSlice" {
402 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
402403 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
403404 const heap_items = try testing.allocator.dupe(u32, items[0..]);
404405 var queue = PQlt.fromOwnedSlice(testing.allocator, heap_items[0..], {});
lib/std/simd.zig+1
......@@ -160,6 +160,7 @@ pub fn extract(
160160}
161161
162162test "vector patterns" {
163 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
163164 const base = @Vector(4, u32){ 10, 20, 30, 40 };
164165 const other_base = @Vector(4, u32){ 55, 66, 77, 88 };
165166
src/AstGen.zig+4-1
......@@ -6876,6 +6876,9 @@ fn asmExpr(
68766876 const constraint = (try astgen.strLitAsString(constraint_token)).index;
68776877 const has_arrow = token_tags[symbolic_name + 4] == .arrow;
68786878 if (has_arrow) {
6879 if (output_type_bits != 0) {
6880 return astgen.failNode(output_node, "inline assembly allows up to one output value", .{});
6881 }
68796882 output_type_bits |= @as(u32, 1) << @intCast(u5, i);
68806883 const out_type_node = node_datas[output_node].lhs;
68816884 const out_type_inst = try typeExpr(gz, scope, out_type_node);
......@@ -6892,7 +6895,7 @@ fn asmExpr(
68926895 outputs[i] = .{
68936896 .name = name,
68946897 .constraint = constraint,
6895 .operand = try localVarRef(gz, scope, rl, node, ident_token),
6898 .operand = try localVarRef(gz, scope, .ref, node, ident_token),
68966899 };
68976900 }
68986901 }
src/Sema.zig+74-32
......@@ -7774,7 +7774,12 @@ fn zirSwitchCapture(
77747774 }
77757775
77767776 switch (operand_ty.zigTypeTag()) {
7777 .ErrorSet => return sema.bitCast(block, block.switch_else_err_ty.?, operand, operand_src),
7777 .ErrorSet => if (block.switch_else_err_ty) |some| {
7778 return sema.bitCast(block, some, operand, operand_src);
7779 } else {
7780 try block.addUnreachable(operand_src, false);
7781 return Air.Inst.Ref.unreachable_value;
7782 },
77787783 else => return operand,
77797784 }
77807785 }
......@@ -8194,7 +8199,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
81948199 );
81958200 }
81968201 else_error_ty = Type.@"anyerror";
8197 } else {
8202 } else else_validation: {
81988203 var maybe_msg: ?*Module.ErrorMsg = null;
81998204 errdefer if (maybe_msg) |msg| msg.destroy(sema.gpa);
82008205
......@@ -8231,6 +8236,27 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
82318236 }
82328237
82338238 if (special_prong == .@"else" and seen_errors.count() == operand_ty.errorSetNames().len) {
8239
8240 // In order to enable common patterns for generic code allow simple else bodies
8241 // else => unreachable,
8242 // else => return,
8243 // else => |e| return e,
8244 // even if all the possible errors were already handled.
8245 const tags = sema.code.instructions.items(.tag);
8246 for (special.body) |else_inst| switch (tags[else_inst]) {
8247 .dbg_block_begin,
8248 .dbg_block_end,
8249 .dbg_stmt,
8250 .dbg_var_val,
8251 .switch_capture,
8252 .ret_type,
8253 .as_node,
8254 .ret_node,
8255 .@"unreachable",
8256 => {},
8257 else => break,
8258 } else break :else_validation;
8259
82348260 return sema.fail(
82358261 block,
82368262 special_prong_src,
......@@ -11308,43 +11334,40 @@ fn zirAsm(
1130811334 try sema.requireRuntimeBlock(block, src);
1130911335 }
1131011336
11311 if (outputs_len > 1) {
11312 return sema.fail(block, src, "TODO implement Sema for asm with more than 1 output", .{});
11313 }
11314
1131511337 var extra_i = extra.end;
1131611338 var output_type_bits = extra.data.output_type_bits;
1131711339 var needed_capacity: usize = @typeInfo(Air.Asm).Struct.fields.len + outputs_len + inputs_len;
1131811340
11319 const Output = struct {
11320 constraint: []const u8,
11321 name: []const u8,
11322 ty: Type,
11323 };
11324 const output: ?Output = if (outputs_len == 0) null else blk: {
11341 const ConstraintName = struct { c: []const u8, n: []const u8 };
11342 const out_args = try sema.arena.alloc(Air.Inst.Ref, outputs_len);
11343 const outputs = try sema.arena.alloc(ConstraintName, outputs_len);
11344 var expr_ty = Air.Inst.Ref.void_type;
11345
11346 for (out_args) |*arg, out_i| {
1132511347 const output = sema.code.extraData(Zir.Inst.Asm.Output, extra_i);
1132611348 extra_i = output.end;
1132711349
1132811350 const is_type = @truncate(u1, output_type_bits) != 0;
1132911351 output_type_bits >>= 1;
1133011352
11331 if (!is_type) {
11332 return sema.fail(block, src, "TODO implement Sema for asm with non `->` output", .{});
11353 if (is_type) {
11354 // Indicate the output is the asm instruction return value.
11355 arg.* = .none;
11356 const out_ty = try sema.resolveType(block, ret_ty_src, output.data.operand);
11357 expr_ty = try sema.addType(out_ty);
11358 } else {
11359 arg.* = try sema.resolveInst(output.data.operand);
1133311360 }
1133411361
1133511362 const constraint = sema.code.nullTerminatedString(output.data.constraint);
1133611363 const name = sema.code.nullTerminatedString(output.data.name);
1133711364 needed_capacity += (constraint.len + name.len + (2 + 3)) / 4;
1133811365
11339 break :blk Output{
11340 .constraint = constraint,
11341 .name = name,
11342 .ty = try sema.resolveType(block, ret_ty_src, output.data.operand),
11343 };
11344 };
11366 outputs[out_i] = .{ .c = constraint, .n = name };
11367 }
1134511368
1134611369 const args = try sema.arena.alloc(Air.Inst.Ref, inputs_len);
11347 const inputs = try sema.arena.alloc(struct { c: []const u8, n: []const u8 }, inputs_len);
11370 const inputs = try sema.arena.alloc(ConstraintName, inputs_len);
1134811371
1134911372 for (args) |*arg, arg_i| {
1135011373 const input = sema.code.extraData(Zir.Inst.Asm.Input, extra_i);
......@@ -11379,7 +11402,7 @@ fn zirAsm(
1137911402 const asm_air = try block.addInst(.{
1138011403 .tag = .assembly,
1138111404 .data = .{ .ty_pl = .{
11382 .ty = if (output) |o| try sema.addType(o.ty) else Air.Inst.Ref.void_type,
11405 .ty = expr_ty,
1138311406 .payload = sema.addExtraAssumeCapacity(Air.Asm{
1138411407 .source_len = @intCast(u32, asm_source.len),
1138511408 .outputs_len = outputs_len,
......@@ -11388,18 +11411,15 @@ fn zirAsm(
1138811411 }),
1138911412 } },
1139011413 });
11391 if (output != null) {
11392 // Indicate the output is the asm instruction return value.
11393 sema.air_extra.appendAssumeCapacity(@enumToInt(Air.Inst.Ref.none));
11394 }
11414 sema.appendRefsAssumeCapacity(out_args);
1139511415 sema.appendRefsAssumeCapacity(args);
11396 if (output) |o| {
11416 for (outputs) |o| {
1139711417 const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice());
11398 mem.copy(u8, buffer, o.constraint);
11399 buffer[o.constraint.len] = 0;
11400 mem.copy(u8, buffer[o.constraint.len + 1 ..], o.name);
11401 buffer[o.constraint.len + 1 + o.name.len] = 0;
11402 sema.air_extra.items.len += (o.constraint.len + o.name.len + (2 + 3)) / 4;
11418 mem.copy(u8, buffer, o.c);
11419 buffer[o.c.len] = 0;
11420 mem.copy(u8, buffer[o.c.len + 1 ..], o.n);
11421 buffer[o.c.len + 1 + o.n.len] = 0;
11422 sema.air_extra.items.len += (o.c.len + o.n.len + (2 + 3)) / 4;
1140311423 }
1140411424 for (inputs) |input| {
1140511425 const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice());
......@@ -21870,6 +21890,28 @@ fn analyzeIsNonErrComptimeOnly(
2187021890 if (ies.is_anyerror) break :blk;
2187121891 if (ies.errors.count() != 0) break :blk;
2187221892 if (maybe_operand_val == null) {
21893 // Try to avoid resolving inferred error set if possible.
21894 if (ies.errors.count() != 0) break :blk;
21895 if (ies.is_anyerror) break :blk;
21896 var it = ies.inferred_error_sets.keyIterator();
21897 while (it.next()) |other_error_set_ptr| {
21898 const other_ies: *Module.Fn.InferredErrorSet = other_error_set_ptr.*;
21899 if (ies == other_ies) continue;
21900 try sema.resolveInferredErrorSet(block, src, other_ies);
21901 if (other_ies.is_anyerror) {
21902 ies.is_anyerror = true;
21903 ies.is_resolved = true;
21904 break :blk;
21905 }
21906
21907 if (other_ies.errors.count() != 0) break :blk;
21908 }
21909 if (ies.func == sema.owner_func) {
21910 // We're checking the inferred errorset of the current function and none of
21911 // its child inferred error sets contained any errors meaning that any value
21912 // so far with this type can't contain errors either.
21913 return Air.Inst.Ref.bool_true;
21914 }
2187321915 try sema.resolveInferredErrorSet(block, src, ies);
2187421916 if (ies.is_anyerror) break :blk;
2187521917 if (ies.errors.count() == 0) return Air.Inst.Ref.bool_true;
src/codegen/llvm.zig+15-10
......@@ -5012,7 +5012,7 @@ pub const FuncGen = struct {
50125012 const compiler_rt_operand_abbrev = compilerRtFloatAbbrev(operand_bits);
50135013
50145014 const compiler_rt_dest_abbrev = compilerRtIntAbbrev(rt_int_bits);
5015 const sign_prefix = if (dest_scalar_ty.isSignedInt()) "" else "un";
5015 const sign_prefix = if (dest_scalar_ty.isSignedInt()) "" else "uns";
50165016
50175017 var fn_name_buf: [64]u8 = undefined;
50185018 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__fix{s}{s}f{s}i", .{
......@@ -5435,10 +5435,6 @@ pub const FuncGen = struct {
54355435 const inputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);
54365436 extra_i += inputs.len;
54375437
5438 if (outputs.len > 1) {
5439 return self.todo("implement llvm codegen for asm with more than 1 output", .{});
5440 }
5441
54425438 var llvm_constraints: std.ArrayListUnmanaged(u8) = .{};
54435439 defer llvm_constraints.deinit(self.gpa);
54445440
......@@ -5446,7 +5442,10 @@ pub const FuncGen = struct {
54465442 defer arena_allocator.deinit();
54475443 const arena = arena_allocator.allocator();
54485444
5449 const llvm_params_len = inputs.len;
5445 const return_count: u8 = for (outputs) |output| {
5446 if (output == .none) break 1;
5447 } else 0;
5448 const llvm_params_len = inputs.len + outputs.len - return_count;
54505449 const llvm_param_types = try arena.alloc(*const llvm.Type, llvm_params_len);
54515450 const llvm_param_values = try arena.alloc(*const llvm.Value, llvm_params_len);
54525451 var llvm_param_i: usize = 0;
......@@ -5456,9 +5455,6 @@ pub const FuncGen = struct {
54565455 try name_map.ensureUnusedCapacity(arena, outputs.len + inputs.len);
54575456
54585457 for (outputs) |output| {
5459 if (output != .none) {
5460 return self.todo("implement inline asm with non-returned output", .{});
5461 }
54625458 const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
54635459 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);
54645460 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
......@@ -5471,6 +5467,15 @@ pub const FuncGen = struct {
54715467 llvm_constraints.appendAssumeCapacity(',');
54725468 }
54735469 llvm_constraints.appendAssumeCapacity('=');
5470 if (output != .none) {
5471 try llvm_constraints.ensureUnusedCapacity(self.gpa, llvm_constraints.capacity + 1);
5472 llvm_constraints.appendAssumeCapacity('*');
5473
5474 const output_inst = try self.resolveInst(output);
5475 llvm_param_values[llvm_param_i] = output_inst;
5476 llvm_param_types[llvm_param_i] = output_inst.typeOf();
5477 llvm_param_i += 1;
5478 }
54745479 llvm_constraints.appendSliceAssumeCapacity(constraint[1..]);
54755480
54765481 name_map.putAssumeCapacityNoClobber(name, {});
......@@ -9284,7 +9289,7 @@ fn needDbgVarWorkaround(dg: *DeclGen, ty: Type) bool {
92849289}
92859290
92869291fn compilerRtIntBits(bits: u16) u16 {
9287 inline for (.{ 8, 16, 32, 64, 128 }) |b| {
9292 inline for (.{ 32, 64, 128 }) |b| {
92889293 if (bits <= b) {
92899294 return b;
92909295 }
test/behavior/error.zig+42
......@@ -754,3 +754,45 @@ test "error union payload is properly aligned" {
754754 const blk = S.foo() catch unreachable;
755755 if (blk.a != 1) unreachable;
756756}
757
758test "ret_ptr doesn't cause own inferred error set to be resolved" {
759 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
760
761 const S = struct {
762 fn foo() !void {}
763
764 fn doTheTest() !void {
765 errdefer @compileError("bad");
766
767 return try @This().foo();
768 }
769 };
770 try S.doTheTest();
771}
772
773test "simple else prong allowed even when all errors handled" {
774 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
775 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
776 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
777
778 const S = struct {
779 fn foo() !u8 {
780 return error.Foo;
781 }
782 };
783 var value = S.foo() catch |err| switch (err) {
784 error.Foo => 255,
785 else => |e| return e,
786 };
787 try expect(value == 255);
788 value = S.foo() catch |err| switch (err) {
789 error.Foo => 255,
790 else => unreachable,
791 };
792 try expect(value == 255);
793 value = S.foo() catch |err| switch (err) {
794 error.Foo => 255,
795 else => return,
796 };
797 try expect(value == 255);
798}