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 {...@@ -87,13 +87,9 @@ pub fn BitReader(endian: std.builtin.Endian, comptime ReaderType: type) type {
87 //copy bytes until we have enough bits, then leave the rest in bit_buffer87 //copy bytes until we have enough bits, then leave the rest in bit_buffer
88 while (out_bits.* < bits) {88 while (out_bits.* < bits) {
89 const n = bits - out_bits.*;89 const n = bits - out_bits.*;
90 const next_byte = self.forward_reader.readByte() catch |err| {90 const next_byte = self.forward_reader.readByte() catch |err| switch (err) {
91 if (err == error.EndOfStream) {91 error.EndOfStream => return @intCast(U, out_buffer),
92 return @intCast(U, out_buffer);92 else => |e| return e,
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);
97 };93 };
9894
99 switch (endian) {95 switch (endian) {
lib/std/io/stream_source.zig+1
...@@ -114,6 +114,7 @@ test "StreamSource (mutable buffer)" {...@@ -114,6 +114,7 @@ test "StreamSource (mutable buffer)" {
114}114}
115115
116test "StreamSource (const buffer)" {116test "StreamSource (const buffer)" {
117 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
117 const buffer: [64]u8 = "Hello, World!".* ++ ([1]u8{0xAA} ** 51);118 const buffer: [64]u8 = "Hello, World!".* ++ ([1]u8{0xAA} ** 51);
118 var source = StreamSource{ .const_buffer = std.io.fixedBufferStream(&buffer) };119 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" {...@@ -573,6 +573,7 @@ test "big.rational setFloatString" {
573}573}
574574
575test "big.rational toFloat" {575test "big.rational toFloat" {
576 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
576 var a = try Rational.init(testing.allocator);577 var a = try Rational.init(testing.allocator);
577 defer a.deinit();578 defer a.deinit();
578579
...@@ -586,6 +587,7 @@ test "big.rational toFloat" {...@@ -586,6 +587,7 @@ test "big.rational toFloat" {
586}587}
587588
588test "big.rational set/to Float round-trip" {589test "big.rational set/to Float round-trip" {
590 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
589 var a = try Rational.init(testing.allocator);591 var a = try Rational.init(testing.allocator);
590 defer a.deinit();592 defer a.deinit();
591 var prng = std.rand.DefaultPrng.init(0x5EED);593 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 {...@@ -1342,7 +1342,8 @@ fn getResolvConf(allocator: mem.Allocator, rc: *ResolvConf) !void {
1342 };1342 };
1343 defer file.close();1343 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();
1346 var line_buf: [512]u8 = undefined;1347 var line_buf: [512]u8 = undefined;
1347 while (stream.readUntilDelimiterOrEof(&line_buf, '\n') catch |err| switch (err) {1348 while (stream.readUntilDelimiterOrEof(&line_buf, '\n') catch |err| switch (err) {
1348 error.StreamTooLong => blk: {1349 error.StreamTooLong => blk: {
...@@ -1353,7 +1354,10 @@ fn getResolvConf(allocator: mem.Allocator, rc: *ResolvConf) !void {...@@ -1353,7 +1354,10 @@ fn getResolvConf(allocator: mem.Allocator, rc: *ResolvConf) !void {
1353 },1354 },
1354 else => |e| return e,1355 else => |e| return e,
1355 }) |line| {1356 }) |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 };
1357 var line_it = mem.tokenize(u8, no_comment_line, " \t");1361 var line_it = mem.tokenize(u8, no_comment_line, " \t");
13581362
1359 const token = line_it.next() orelse continue;1363 const token = line_it.next() orelse continue;
...@@ -1363,7 +1367,8 @@ fn getResolvConf(allocator: mem.Allocator, rc: *ResolvConf) !void {...@@ -1363,7 +1367,8 @@ fn getResolvConf(allocator: mem.Allocator, rc: *ResolvConf) !void {
1363 const name = colon_it.next().?;1367 const name = colon_it.next().?;
1364 const value_txt = colon_it.next() orelse continue;1368 const value_txt = colon_it.next() orelse continue;
1365 const value = std.fmt.parseInt(u8, value_txt, 10) catch |err| switch (err) {1369 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),
1367 error.InvalidCharacter => continue,1372 error.InvalidCharacter => continue,
1368 };1373 };
1369 if (mem.eql(u8, name, "ndots")) {1374 if (mem.eql(u8, name, "ndots")) {
lib/std/net/test.zig+4
...@@ -5,6 +5,7 @@ const mem = std.mem;...@@ -5,6 +5,7 @@ const mem = std.mem;
5const testing = std.testing;5const testing = std.testing;
66
7test "parse and render IPv6 addresses" {7test "parse and render IPv6 addresses" {
8 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
8 if (builtin.os.tag == .wasi) return error.SkipZigTest;9 if (builtin.os.tag == .wasi) return error.SkipZigTest;
910
10 var buffer: [100]u8 = undefined;11 var buffer: [100]u8 = undefined;
...@@ -67,6 +68,7 @@ test "invalid but parseable IPv6 scope ids" {...@@ -67,6 +68,7 @@ test "invalid but parseable IPv6 scope ids" {
67}68}
6869
69test "parse and render IPv4 addresses" {70test "parse and render IPv4 addresses" {
71 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
70 if (builtin.os.tag == .wasi) return error.SkipZigTest;72 if (builtin.os.tag == .wasi) return error.SkipZigTest;
7173
72 var buffer: [18]u8 = undefined;74 var buffer: [18]u8 = undefined;
...@@ -91,6 +93,7 @@ test "parse and render IPv4 addresses" {...@@ -91,6 +93,7 @@ test "parse and render IPv4 addresses" {
91}93}
9294
93test "parse and render UNIX addresses" {95test "parse and render UNIX addresses" {
96 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
94 if (builtin.os.tag == .wasi) return error.SkipZigTest;97 if (builtin.os.tag == .wasi) return error.SkipZigTest;
95 if (!net.has_unix_sockets) return error.SkipZigTest;98 if (!net.has_unix_sockets) return error.SkipZigTest;
9699
...@@ -104,6 +107,7 @@ test "parse and render UNIX addresses" {...@@ -104,6 +107,7 @@ test "parse and render UNIX addresses" {
104}107}
105108
106test "resolve DNS" {109test "resolve DNS" {
110 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
107 if (builtin.os.tag == .wasi) return error.SkipZigTest;111 if (builtin.os.tag == .wasi) return error.SkipZigTest;
108112
109 if (builtin.os.tag == .windows) {113 if (builtin.os.tag == .windows) {
lib/std/priority_queue.zig+1
...@@ -399,6 +399,7 @@ test "std.PriorityQueue: fromOwnedSlice trivial case 1" {...@@ -399,6 +399,7 @@ test "std.PriorityQueue: fromOwnedSlice trivial case 1" {
399}399}
400400
401test "std.PriorityQueue: fromOwnedSlice" {401test "std.PriorityQueue: fromOwnedSlice" {
402 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
402 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };403 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
403 const heap_items = try testing.allocator.dupe(u32, items[0..]);404 const heap_items = try testing.allocator.dupe(u32, items[0..]);
404 var queue = PQlt.fromOwnedSlice(testing.allocator, heap_items[0..], {});405 var queue = PQlt.fromOwnedSlice(testing.allocator, heap_items[0..], {});
lib/std/simd.zig+1
...@@ -160,6 +160,7 @@ pub fn extract(...@@ -160,6 +160,7 @@ pub fn extract(
160}160}
161161
162test "vector patterns" {162test "vector patterns" {
163 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
163 const base = @Vector(4, u32){ 10, 20, 30, 40 };164 const base = @Vector(4, u32){ 10, 20, 30, 40 };
164 const other_base = @Vector(4, u32){ 55, 66, 77, 88 };165 const other_base = @Vector(4, u32){ 55, 66, 77, 88 };
165166
src/AstGen.zig+4-1
...@@ -6876,6 +6876,9 @@ fn asmExpr(...@@ -6876,6 +6876,9 @@ fn asmExpr(
6876 const constraint = (try astgen.strLitAsString(constraint_token)).index;6876 const constraint = (try astgen.strLitAsString(constraint_token)).index;
6877 const has_arrow = token_tags[symbolic_name + 4] == .arrow;6877 const has_arrow = token_tags[symbolic_name + 4] == .arrow;
6878 if (has_arrow) {6878 if (has_arrow) {
6879 if (output_type_bits != 0) {
6880 return astgen.failNode(output_node, "inline assembly allows up to one output value", .{});
6881 }
6879 output_type_bits |= @as(u32, 1) << @intCast(u5, i);6882 output_type_bits |= @as(u32, 1) << @intCast(u5, i);
6880 const out_type_node = node_datas[output_node].lhs;6883 const out_type_node = node_datas[output_node].lhs;
6881 const out_type_inst = try typeExpr(gz, scope, out_type_node);6884 const out_type_inst = try typeExpr(gz, scope, out_type_node);
...@@ -6892,7 +6895,7 @@ fn asmExpr(...@@ -6892,7 +6895,7 @@ fn asmExpr(
6892 outputs[i] = .{6895 outputs[i] = .{
6893 .name = name,6896 .name = name,
6894 .constraint = constraint,6897 .constraint = constraint,
6895 .operand = try localVarRef(gz, scope, rl, node, ident_token),6898 .operand = try localVarRef(gz, scope, .ref, node, ident_token),
6896 };6899 };
6897 }6900 }
6898 }6901 }
src/Sema.zig+74-32
...@@ -7774,7 +7774,12 @@ fn zirSwitchCapture(...@@ -7774,7 +7774,12 @@ fn zirSwitchCapture(
7774 }7774 }
77757775
7776 switch (operand_ty.zigTypeTag()) {7776 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 },
7778 else => return operand,7783 else => return operand,
7779 }7784 }
7780 }7785 }
...@@ -8194,7 +8199,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8194,7 +8199,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8194 );8199 );
8195 }8200 }
8196 else_error_ty = Type.@"anyerror";8201 else_error_ty = Type.@"anyerror";
8197 } else {8202 } else else_validation: {
8198 var maybe_msg: ?*Module.ErrorMsg = null;8203 var maybe_msg: ?*Module.ErrorMsg = null;
8199 errdefer if (maybe_msg) |msg| msg.destroy(sema.gpa);8204 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...@@ -8231,6 +8236,27 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8231 }8236 }
82328237
8233 if (special_prong == .@"else" and seen_errors.count() == operand_ty.errorSetNames().len) {8238 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
8234 return sema.fail(8260 return sema.fail(
8235 block,8261 block,
8236 special_prong_src,8262 special_prong_src,
...@@ -11308,43 +11334,40 @@ fn zirAsm(...@@ -11308,43 +11334,40 @@ fn zirAsm(
11308 try sema.requireRuntimeBlock(block, src);11334 try sema.requireRuntimeBlock(block, src);
11309 }11335 }
1131011336
11311 if (outputs_len > 1) {
11312 return sema.fail(block, src, "TODO implement Sema for asm with more than 1 output", .{});
11313 }
11314
11315 var extra_i = extra.end;11337 var extra_i = extra.end;
11316 var output_type_bits = extra.data.output_type_bits;11338 var output_type_bits = extra.data.output_type_bits;
11317 var needed_capacity: usize = @typeInfo(Air.Asm).Struct.fields.len + outputs_len + inputs_len;11339 var needed_capacity: usize = @typeInfo(Air.Asm).Struct.fields.len + outputs_len + inputs_len;
1131811340
11319 const Output = struct {11341 const ConstraintName = struct { c: []const u8, n: []const u8 };
11320 constraint: []const u8,11342 const out_args = try sema.arena.alloc(Air.Inst.Ref, outputs_len);
11321 name: []const u8,11343 const outputs = try sema.arena.alloc(ConstraintName, outputs_len);
11322 ty: Type,11344 var expr_ty = Air.Inst.Ref.void_type;
11323 };11345
11324 const output: ?Output = if (outputs_len == 0) null else blk: {11346 for (out_args) |*arg, out_i| {
11325 const output = sema.code.extraData(Zir.Inst.Asm.Output, extra_i);11347 const output = sema.code.extraData(Zir.Inst.Asm.Output, extra_i);
11326 extra_i = output.end;11348 extra_i = output.end;
1132711349
11328 const is_type = @truncate(u1, output_type_bits) != 0;11350 const is_type = @truncate(u1, output_type_bits) != 0;
11329 output_type_bits >>= 1;11351 output_type_bits >>= 1;
1133011352
11331 if (!is_type) {11353 if (is_type) {
11332 return sema.fail(block, src, "TODO implement Sema for asm with non `->` output", .{});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);
11333 }11360 }
1133411361
11335 const constraint = sema.code.nullTerminatedString(output.data.constraint);11362 const constraint = sema.code.nullTerminatedString(output.data.constraint);
11336 const name = sema.code.nullTerminatedString(output.data.name);11363 const name = sema.code.nullTerminatedString(output.data.name);
11337 needed_capacity += (constraint.len + name.len + (2 + 3)) / 4;11364 needed_capacity += (constraint.len + name.len + (2 + 3)) / 4;
1133811365
11339 break :blk Output{11366 outputs[out_i] = .{ .c = constraint, .n = name };
11340 .constraint = constraint,11367 }
11341 .name = name,
11342 .ty = try sema.resolveType(block, ret_ty_src, output.data.operand),
11343 };
11344 };
1134511368
11346 const args = try sema.arena.alloc(Air.Inst.Ref, inputs_len);11369 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
11349 for (args) |*arg, arg_i| {11372 for (args) |*arg, arg_i| {
11350 const input = sema.code.extraData(Zir.Inst.Asm.Input, extra_i);11373 const input = sema.code.extraData(Zir.Inst.Asm.Input, extra_i);
...@@ -11379,7 +11402,7 @@ fn zirAsm(...@@ -11379,7 +11402,7 @@ fn zirAsm(
11379 const asm_air = try block.addInst(.{11402 const asm_air = try block.addInst(.{
11380 .tag = .assembly,11403 .tag = .assembly,
11381 .data = .{ .ty_pl = .{11404 .data = .{ .ty_pl = .{
11382 .ty = if (output) |o| try sema.addType(o.ty) else Air.Inst.Ref.void_type,11405 .ty = expr_ty,
11383 .payload = sema.addExtraAssumeCapacity(Air.Asm{11406 .payload = sema.addExtraAssumeCapacity(Air.Asm{
11384 .source_len = @intCast(u32, asm_source.len),11407 .source_len = @intCast(u32, asm_source.len),
11385 .outputs_len = outputs_len,11408 .outputs_len = outputs_len,
...@@ -11388,18 +11411,15 @@ fn zirAsm(...@@ -11388,18 +11411,15 @@ fn zirAsm(
11388 }),11411 }),
11389 } },11412 } },
11390 });11413 });
11391 if (output != null) {11414 sema.appendRefsAssumeCapacity(out_args);
11392 // Indicate the output is the asm instruction return value.
11393 sema.air_extra.appendAssumeCapacity(@enumToInt(Air.Inst.Ref.none));
11394 }
11395 sema.appendRefsAssumeCapacity(args);11415 sema.appendRefsAssumeCapacity(args);
11396 if (output) |o| {11416 for (outputs) |o| {
11397 const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice());11417 const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice());
11398 mem.copy(u8, buffer, o.constraint);11418 mem.copy(u8, buffer, o.c);
11399 buffer[o.constraint.len] = 0;11419 buffer[o.c.len] = 0;
11400 mem.copy(u8, buffer[o.constraint.len + 1 ..], o.name);11420 mem.copy(u8, buffer[o.c.len + 1 ..], o.n);
11401 buffer[o.constraint.len + 1 + o.name.len] = 0;11421 buffer[o.c.len + 1 + o.n.len] = 0;
11402 sema.air_extra.items.len += (o.constraint.len + o.name.len + (2 + 3)) / 4;11422 sema.air_extra.items.len += (o.c.len + o.n.len + (2 + 3)) / 4;
11403 }11423 }
11404 for (inputs) |input| {11424 for (inputs) |input| {
11405 const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice());11425 const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice());
...@@ -21870,6 +21890,28 @@ fn analyzeIsNonErrComptimeOnly(...@@ -21870,6 +21890,28 @@ fn analyzeIsNonErrComptimeOnly(
21870 if (ies.is_anyerror) break :blk;21890 if (ies.is_anyerror) break :blk;
21871 if (ies.errors.count() != 0) break :blk;21891 if (ies.errors.count() != 0) break :blk;
21872 if (maybe_operand_val == null) {21892 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 }
21873 try sema.resolveInferredErrorSet(block, src, ies);21915 try sema.resolveInferredErrorSet(block, src, ies);
21874 if (ies.is_anyerror) break :blk;21916 if (ies.is_anyerror) break :blk;
21875 if (ies.errors.count() == 0) return Air.Inst.Ref.bool_true;21917 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 {...@@ -5012,7 +5012,7 @@ pub const FuncGen = struct {
5012 const compiler_rt_operand_abbrev = compilerRtFloatAbbrev(operand_bits);5012 const compiler_rt_operand_abbrev = compilerRtFloatAbbrev(operand_bits);
50135013
5014 const compiler_rt_dest_abbrev = compilerRtIntAbbrev(rt_int_bits);5014 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
5017 var fn_name_buf: [64]u8 = undefined;5017 var fn_name_buf: [64]u8 = undefined;
5018 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__fix{s}{s}f{s}i", .{5018 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__fix{s}{s}f{s}i", .{
...@@ -5435,10 +5435,6 @@ pub const FuncGen = struct {...@@ -5435,10 +5435,6 @@ pub const FuncGen = struct {
5435 const inputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);5435 const inputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);
5436 extra_i += inputs.len;5436 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
5442 var llvm_constraints: std.ArrayListUnmanaged(u8) = .{};5438 var llvm_constraints: std.ArrayListUnmanaged(u8) = .{};
5443 defer llvm_constraints.deinit(self.gpa);5439 defer llvm_constraints.deinit(self.gpa);
54445440
...@@ -5446,7 +5442,10 @@ pub const FuncGen = struct {...@@ -5446,7 +5442,10 @@ pub const FuncGen = struct {
5446 defer arena_allocator.deinit();5442 defer arena_allocator.deinit();
5447 const arena = arena_allocator.allocator();5443 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;
5450 const llvm_param_types = try arena.alloc(*const llvm.Type, llvm_params_len);5449 const llvm_param_types = try arena.alloc(*const llvm.Type, llvm_params_len);
5451 const llvm_param_values = try arena.alloc(*const llvm.Value, llvm_params_len);5450 const llvm_param_values = try arena.alloc(*const llvm.Value, llvm_params_len);
5452 var llvm_param_i: usize = 0;5451 var llvm_param_i: usize = 0;
...@@ -5456,9 +5455,6 @@ pub const FuncGen = struct {...@@ -5456,9 +5455,6 @@ pub const FuncGen = struct {
5456 try name_map.ensureUnusedCapacity(arena, outputs.len + inputs.len);5455 try name_map.ensureUnusedCapacity(arena, outputs.len + inputs.len);
54575456
5458 for (outputs) |output| {5457 for (outputs) |output| {
5459 if (output != .none) {
5460 return self.todo("implement inline asm with non-returned output", .{});
5461 }
5462 const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);5458 const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
5463 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);5459 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);
5464 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);5460 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
...@@ -5471,6 +5467,15 @@ pub const FuncGen = struct {...@@ -5471,6 +5467,15 @@ pub const FuncGen = struct {
5471 llvm_constraints.appendAssumeCapacity(',');5467 llvm_constraints.appendAssumeCapacity(',');
5472 }5468 }
5473 llvm_constraints.appendAssumeCapacity('=');5469 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 }
5474 llvm_constraints.appendSliceAssumeCapacity(constraint[1..]);5479 llvm_constraints.appendSliceAssumeCapacity(constraint[1..]);
54755480
5476 name_map.putAssumeCapacityNoClobber(name, {});5481 name_map.putAssumeCapacityNoClobber(name, {});
...@@ -9284,7 +9289,7 @@ fn needDbgVarWorkaround(dg: *DeclGen, ty: Type) bool {...@@ -9284,7 +9289,7 @@ fn needDbgVarWorkaround(dg: *DeclGen, ty: Type) bool {
9284}9289}
92859290
9286fn compilerRtIntBits(bits: u16) u16 {9291fn compilerRtIntBits(bits: u16) u16 {
9287 inline for (.{ 8, 16, 32, 64, 128 }) |b| {9292 inline for (.{ 32, 64, 128 }) |b| {
9288 if (bits <= b) {9293 if (bits <= b) {
9289 return b;9294 return b;
9290 }9295 }
test/behavior/error.zig+42
...@@ -754,3 +754,45 @@ test "error union payload is properly aligned" {...@@ -754,3 +754,45 @@ test "error union payload is properly aligned" {
754 const blk = S.foo() catch unreachable;754 const blk = S.foo() catch unreachable;
755 if (blk.a != 1) unreachable;755 if (blk.a != 1) unreachable;
756}756}
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}