| author | |
| committer | |
| log | 6ff7b437ff34e9a416a041c0c0ff8a65bae8daf5 |
| tree | e8be8a2b2a1fa6524bead911f3607941d005d8ee |
| parent | 3cb387338234620e00645417565dc234dc5105c2 |
| parent | 413577c881963559f7f357bfd90f4ade6d6de20d |
| signature |
`zig2 build test-std` finale11 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 | 87 | //copy bytes until we have enough bits, then leave the rest in bit_buffer |
| 88 | 88 | while (out_bits.* < bits) { |
| 89 | 89 | 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, | |
| 97 | 93 | }; |
| 98 | 94 | |
| 99 | 95 | switch (endian) { |
lib/std/io/stream_source.zig+1| ... | ... | @@ -114,6 +114,7 @@ test "StreamSource (mutable buffer)" { |
| 114 | 114 | } |
| 115 | 115 | |
| 116 | 116 | test "StreamSource (const buffer)" { |
| 117 | if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; | |
| 117 | 118 | const buffer: [64]u8 = "Hello, World!".* ++ ([1]u8{0xAA} ** 51); |
| 118 | 119 | var source = StreamSource{ .const_buffer = std.io.fixedBufferStream(&buffer) }; |
| 119 | 120 |
lib/std/math/big/rational.zig+2| ... | ... | @@ -573,6 +573,7 @@ test "big.rational setFloatString" { |
| 573 | 573 | } |
| 574 | 574 | |
| 575 | 575 | test "big.rational toFloat" { |
| 576 | if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; | |
| 576 | 577 | var a = try Rational.init(testing.allocator); |
| 577 | 578 | defer a.deinit(); |
| 578 | 579 | |
| ... | ... | @@ -586,6 +587,7 @@ test "big.rational toFloat" { |
| 586 | 587 | } |
| 587 | 588 | |
| 588 | 589 | test "big.rational set/to Float round-trip" { |
| 590 | if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; | |
| 589 | 591 | var a = try Rational.init(testing.allocator); |
| 590 | 592 | defer a.deinit(); |
| 591 | 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 | 1342 | }; |
| 1343 | 1343 | defer file.close(); |
| 1344 | 1344 | |
| 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 | 1347 | var line_buf: [512]u8 = undefined; |
| 1347 | 1348 | while (stream.readUntilDelimiterOrEof(&line_buf, '\n') catch |err| switch (err) { |
| 1348 | 1349 | error.StreamTooLong => blk: { |
| ... | ... | @@ -1353,7 +1354,10 @@ fn getResolvConf(allocator: mem.Allocator, rc: *ResolvConf) !void { |
| 1353 | 1354 | }, |
| 1354 | 1355 | else => |e| return e, |
| 1355 | 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 | 1361 | var line_it = mem.tokenize(u8, no_comment_line, " \t"); |
| 1358 | 1362 | |
| 1359 | 1363 | const token = line_it.next() orelse continue; |
| ... | ... | @@ -1363,7 +1367,8 @@ fn getResolvConf(allocator: mem.Allocator, rc: *ResolvConf) !void { |
| 1363 | 1367 | const name = colon_it.next().?; |
| 1364 | 1368 | const value_txt = colon_it.next() orelse continue; |
| 1365 | 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 | 1372 | error.InvalidCharacter => continue, |
| 1368 | 1373 | }; |
| 1369 | 1374 | if (mem.eql(u8, name, "ndots")) { |
lib/std/net/test.zig+4| ... | ... | @@ -5,6 +5,7 @@ const mem = std.mem; |
| 5 | 5 | const testing = std.testing; |
| 6 | 6 | |
| 7 | 7 | test "parse and render IPv6 addresses" { |
| 8 | if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; | |
| 8 | 9 | if (builtin.os.tag == .wasi) return error.SkipZigTest; |
| 9 | 10 | |
| 10 | 11 | var buffer: [100]u8 = undefined; |
| ... | ... | @@ -67,6 +68,7 @@ test "invalid but parseable IPv6 scope ids" { |
| 67 | 68 | } |
| 68 | 69 | |
| 69 | 70 | test "parse and render IPv4 addresses" { |
| 71 | if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; | |
| 70 | 72 | if (builtin.os.tag == .wasi) return error.SkipZigTest; |
| 71 | 73 | |
| 72 | 74 | var buffer: [18]u8 = undefined; |
| ... | ... | @@ -91,6 +93,7 @@ test "parse and render IPv4 addresses" { |
| 91 | 93 | } |
| 92 | 94 | |
| 93 | 95 | test "parse and render UNIX addresses" { |
| 96 | if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; | |
| 94 | 97 | if (builtin.os.tag == .wasi) return error.SkipZigTest; |
| 95 | 98 | if (!net.has_unix_sockets) return error.SkipZigTest; |
| 96 | 99 | |
| ... | ... | @@ -104,6 +107,7 @@ test "parse and render UNIX addresses" { |
| 104 | 107 | } |
| 105 | 108 | |
| 106 | 109 | test "resolve DNS" { |
| 110 | if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; | |
| 107 | 111 | if (builtin.os.tag == .wasi) return error.SkipZigTest; |
| 108 | 112 | |
| 109 | 113 | if (builtin.os.tag == .windows) { |
lib/std/priority_queue.zig+1| ... | ... | @@ -399,6 +399,7 @@ test "std.PriorityQueue: fromOwnedSlice trivial case 1" { |
| 399 | 399 | } |
| 400 | 400 | |
| 401 | 401 | test "std.PriorityQueue: fromOwnedSlice" { |
| 402 | if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; | |
| 402 | 403 | const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 }; |
| 403 | 404 | const heap_items = try testing.allocator.dupe(u32, items[0..]); |
| 404 | 405 | var queue = PQlt.fromOwnedSlice(testing.allocator, heap_items[0..], {}); |
lib/std/simd.zig+1| ... | ... | @@ -160,6 +160,7 @@ pub fn extract( |
| 160 | 160 | } |
| 161 | 161 | |
| 162 | 162 | test "vector patterns" { |
| 163 | if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; | |
| 163 | 164 | const base = @Vector(4, u32){ 10, 20, 30, 40 }; |
| 164 | 165 | const other_base = @Vector(4, u32){ 55, 66, 77, 88 }; |
| 165 | 166 |
src/AstGen.zig+4-1| ... | ... | @@ -6876,6 +6876,9 @@ fn asmExpr( |
| 6876 | 6876 | const constraint = (try astgen.strLitAsString(constraint_token)).index; |
| 6877 | 6877 | const has_arrow = token_tags[symbolic_name + 4] == .arrow; |
| 6878 | 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 | 6882 | output_type_bits |= @as(u32, 1) << @intCast(u5, i); |
| 6880 | 6883 | const out_type_node = node_datas[output_node].lhs; |
| 6881 | 6884 | const out_type_inst = try typeExpr(gz, scope, out_type_node); |
| ... | ... | @@ -6892,7 +6895,7 @@ fn asmExpr( |
| 6892 | 6895 | outputs[i] = .{ |
| 6893 | 6896 | .name = name, |
| 6894 | 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 | 7774 | } |
| 7775 | 7775 | |
| 7776 | 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 | 7783 | else => return operand, |
| 7779 | 7784 | } |
| 7780 | 7785 | } |
| ... | ... | @@ -8194,7 +8199,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8194 | 8199 | ); |
| 8195 | 8200 | } |
| 8196 | 8201 | else_error_ty = Type.@"anyerror"; |
| 8197 | } else { | |
| 8202 | } else else_validation: { | |
| 8198 | 8203 | var maybe_msg: ?*Module.ErrorMsg = null; |
| 8199 | 8204 | errdefer if (maybe_msg) |msg| msg.destroy(sema.gpa); |
| 8200 | 8205 | |
| ... | ... | @@ -8231,6 +8236,27 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8231 | 8236 | } |
| 8232 | 8237 | |
| 8233 | 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 | 8260 | return sema.fail( |
| 8235 | 8261 | block, |
| 8236 | 8262 | special_prong_src, |
| ... | ... | @@ -11308,43 +11334,40 @@ fn zirAsm( |
| 11308 | 11334 | try sema.requireRuntimeBlock(block, src); |
| 11309 | 11335 | } |
| 11310 | 11336 | |
| 11311 | if (outputs_len > 1) { | |
| 11312 | return sema.fail(block, src, "TODO implement Sema for asm with more than 1 output", .{}); | |
| 11313 | } | |
| 11314 | ||
| 11315 | 11337 | var extra_i = extra.end; |
| 11316 | 11338 | var output_type_bits = extra.data.output_type_bits; |
| 11317 | 11339 | var needed_capacity: usize = @typeInfo(Air.Asm).Struct.fields.len + outputs_len + inputs_len; |
| 11318 | 11340 | |
| 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| { | |
| 11325 | 11347 | const output = sema.code.extraData(Zir.Inst.Asm.Output, extra_i); |
| 11326 | 11348 | extra_i = output.end; |
| 11327 | 11349 | |
| 11328 | 11350 | const is_type = @truncate(u1, output_type_bits) != 0; |
| 11329 | 11351 | output_type_bits >>= 1; |
| 11330 | 11352 | |
| 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); | |
| 11333 | 11360 | } |
| 11334 | 11361 | |
| 11335 | 11362 | const constraint = sema.code.nullTerminatedString(output.data.constraint); |
| 11336 | 11363 | const name = sema.code.nullTerminatedString(output.data.name); |
| 11337 | 11364 | needed_capacity += (constraint.len + name.len + (2 + 3)) / 4; |
| 11338 | 11365 | |
| 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 | } | |
| 11345 | 11368 | |
| 11346 | 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); | |
| 11348 | 11371 | |
| 11349 | 11372 | for (args) |*arg, arg_i| { |
| 11350 | 11373 | const input = sema.code.extraData(Zir.Inst.Asm.Input, extra_i); |
| ... | ... | @@ -11379,7 +11402,7 @@ fn zirAsm( |
| 11379 | 11402 | const asm_air = try block.addInst(.{ |
| 11380 | 11403 | .tag = .assembly, |
| 11381 | 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 | 11406 | .payload = sema.addExtraAssumeCapacity(Air.Asm{ |
| 11384 | 11407 | .source_len = @intCast(u32, asm_source.len), |
| 11385 | 11408 | .outputs_len = outputs_len, |
| ... | ... | @@ -11388,18 +11411,15 @@ fn zirAsm( |
| 11388 | 11411 | }), |
| 11389 | 11412 | } }, |
| 11390 | 11413 | }); |
| 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); | |
| 11395 | 11415 | sema.appendRefsAssumeCapacity(args); |
| 11396 | if (output) |o| { | |
| 11416 | for (outputs) |o| { | |
| 11397 | 11417 | 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; | |
| 11403 | 11423 | } |
| 11404 | 11424 | for (inputs) |input| { |
| 11405 | 11425 | const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice()); |
| ... | ... | @@ -21870,6 +21890,28 @@ fn analyzeIsNonErrComptimeOnly( |
| 21870 | 21890 | if (ies.is_anyerror) break :blk; |
| 21871 | 21891 | if (ies.errors.count() != 0) break :blk; |
| 21872 | 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 | 21915 | try sema.resolveInferredErrorSet(block, src, ies); |
| 21874 | 21916 | if (ies.is_anyerror) break :blk; |
| 21875 | 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 | 5012 | const compiler_rt_operand_abbrev = compilerRtFloatAbbrev(operand_bits); |
| 5013 | 5013 | |
| 5014 | 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"; | |
| 5016 | 5016 | |
| 5017 | 5017 | var fn_name_buf: [64]u8 = undefined; |
| 5018 | 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 | 5435 | const inputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]); |
| 5436 | 5436 | extra_i += inputs.len; |
| 5437 | 5437 | |
| 5438 | if (outputs.len > 1) { | |
| 5439 | return self.todo("implement llvm codegen for asm with more than 1 output", .{}); | |
| 5440 | } | |
| 5441 | ||
| 5442 | 5438 | var llvm_constraints: std.ArrayListUnmanaged(u8) = .{}; |
| 5443 | 5439 | defer llvm_constraints.deinit(self.gpa); |
| 5444 | 5440 | |
| ... | ... | @@ -5446,7 +5442,10 @@ pub const FuncGen = struct { |
| 5446 | 5442 | defer arena_allocator.deinit(); |
| 5447 | 5443 | const arena = arena_allocator.allocator(); |
| 5448 | 5444 | |
| 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 | 5449 | const llvm_param_types = try arena.alloc(*const llvm.Type, llvm_params_len); |
| 5451 | 5450 | const llvm_param_values = try arena.alloc(*const llvm.Value, llvm_params_len); |
| 5452 | 5451 | var llvm_param_i: usize = 0; |
| ... | ... | @@ -5456,9 +5455,6 @@ pub const FuncGen = struct { |
| 5456 | 5455 | try name_map.ensureUnusedCapacity(arena, outputs.len + inputs.len); |
| 5457 | 5456 | |
| 5458 | 5457 | for (outputs) |output| { |
| 5459 | if (output != .none) { | |
| 5460 | return self.todo("implement inline asm with non-returned output", .{}); | |
| 5461 | } | |
| 5462 | 5458 | const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); |
| 5463 | 5459 | const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0); |
| 5464 | 5460 | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); |
| ... | ... | @@ -5471,6 +5467,15 @@ pub const FuncGen = struct { |
| 5471 | 5467 | llvm_constraints.appendAssumeCapacity(','); |
| 5472 | 5468 | } |
| 5473 | 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 | 5479 | llvm_constraints.appendSliceAssumeCapacity(constraint[1..]); |
| 5475 | 5480 | |
| 5476 | 5481 | name_map.putAssumeCapacityNoClobber(name, {}); |
| ... | ... | @@ -9284,7 +9289,7 @@ fn needDbgVarWorkaround(dg: *DeclGen, ty: Type) bool { |
| 9284 | 9289 | } |
| 9285 | 9290 | |
| 9286 | 9291 | fn compilerRtIntBits(bits: u16) u16 { |
| 9287 | inline for (.{ 8, 16, 32, 64, 128 }) |b| { | |
| 9292 | inline for (.{ 32, 64, 128 }) |b| { | |
| 9288 | 9293 | if (bits <= b) { |
| 9289 | 9294 | return b; |
| 9290 | 9295 | } |
test/behavior/error.zig+42| ... | ... | @@ -754,3 +754,45 @@ test "error union payload is properly aligned" { |
| 754 | 754 | const blk = S.foo() catch unreachable; |
| 755 | 755 | if (blk.a != 1) unreachable; |
| 756 | 756 | } |
| 757 | ||
| 758 | test "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 | ||
| 773 | test "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 | } |