mirror of
https://github.com/ziglang/zig.git
synced 2025-12-28 09:03:21 +00:00
Merge pull request #11813 from Vexu/stage2
`zig2 build test-std` finale
This commit is contained in:
commit
6ff7b437ff
@ -87,13 +87,9 @@ pub fn BitReader(endian: std.builtin.Endian, comptime ReaderType: type) type {
|
||||
//copy bytes until we have enough bits, then leave the rest in bit_buffer
|
||||
while (out_bits.* < bits) {
|
||||
const n = bits - out_bits.*;
|
||||
const next_byte = self.forward_reader.readByte() catch |err| {
|
||||
if (err == error.EndOfStream) {
|
||||
return @intCast(U, out_buffer);
|
||||
}
|
||||
//@BUG: See #1810. Not sure if the bug is that I have to do this for some
|
||||
// streams, or that I don't for streams with emtpy errorsets.
|
||||
return @errSetCast(Error, err);
|
||||
const next_byte = self.forward_reader.readByte() catch |err| switch (err) {
|
||||
error.EndOfStream => return @intCast(U, out_buffer),
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
switch (endian) {
|
||||
|
||||
@ -114,6 +114,7 @@ test "StreamSource (mutable buffer)" {
|
||||
}
|
||||
|
||||
test "StreamSource (const buffer)" {
|
||||
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
|
||||
const buffer: [64]u8 = "Hello, World!".* ++ ([1]u8{0xAA} ** 51);
|
||||
var source = StreamSource{ .const_buffer = std.io.fixedBufferStream(&buffer) };
|
||||
|
||||
|
||||
@ -573,6 +573,7 @@ test "big.rational setFloatString" {
|
||||
}
|
||||
|
||||
test "big.rational toFloat" {
|
||||
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
|
||||
var a = try Rational.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
|
||||
@ -586,6 +587,7 @@ test "big.rational toFloat" {
|
||||
}
|
||||
|
||||
test "big.rational set/to Float round-trip" {
|
||||
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
|
||||
var a = try Rational.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
var prng = std.rand.DefaultPrng.init(0x5EED);
|
||||
|
||||
@ -1342,7 +1342,8 @@ fn getResolvConf(allocator: mem.Allocator, rc: *ResolvConf) !void {
|
||||
};
|
||||
defer file.close();
|
||||
|
||||
const stream = std.io.bufferedReader(file.reader()).reader();
|
||||
var buf_reader = std.io.bufferedReader(file.reader());
|
||||
const stream = buf_reader.reader();
|
||||
var line_buf: [512]u8 = undefined;
|
||||
while (stream.readUntilDelimiterOrEof(&line_buf, '\n') catch |err| switch (err) {
|
||||
error.StreamTooLong => blk: {
|
||||
@ -1353,7 +1354,10 @@ fn getResolvConf(allocator: mem.Allocator, rc: *ResolvConf) !void {
|
||||
},
|
||||
else => |e| return e,
|
||||
}) |line| {
|
||||
const no_comment_line = mem.split(u8, line, "#").next().?;
|
||||
const no_comment_line = no_comment_line: {
|
||||
var split = mem.split(u8, line, "#");
|
||||
break :no_comment_line split.next().?;
|
||||
};
|
||||
var line_it = mem.tokenize(u8, no_comment_line, " \t");
|
||||
|
||||
const token = line_it.next() orelse continue;
|
||||
@ -1363,7 +1367,8 @@ fn getResolvConf(allocator: mem.Allocator, rc: *ResolvConf) !void {
|
||||
const name = colon_it.next().?;
|
||||
const value_txt = colon_it.next() orelse continue;
|
||||
const value = std.fmt.parseInt(u8, value_txt, 10) catch |err| switch (err) {
|
||||
error.Overflow => 255,
|
||||
// TODO https://github.com/ziglang/zig/issues/11812
|
||||
error.Overflow => @as(u8, 255),
|
||||
error.InvalidCharacter => continue,
|
||||
};
|
||||
if (mem.eql(u8, name, "ndots")) {
|
||||
|
||||
@ -5,6 +5,7 @@ const mem = std.mem;
|
||||
const testing = std.testing;
|
||||
|
||||
test "parse and render IPv6 addresses" {
|
||||
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
|
||||
if (builtin.os.tag == .wasi) return error.SkipZigTest;
|
||||
|
||||
var buffer: [100]u8 = undefined;
|
||||
@ -67,6 +68,7 @@ test "invalid but parseable IPv6 scope ids" {
|
||||
}
|
||||
|
||||
test "parse and render IPv4 addresses" {
|
||||
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
|
||||
if (builtin.os.tag == .wasi) return error.SkipZigTest;
|
||||
|
||||
var buffer: [18]u8 = undefined;
|
||||
@ -91,6 +93,7 @@ test "parse and render IPv4 addresses" {
|
||||
}
|
||||
|
||||
test "parse and render UNIX addresses" {
|
||||
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
|
||||
if (builtin.os.tag == .wasi) return error.SkipZigTest;
|
||||
if (!net.has_unix_sockets) return error.SkipZigTest;
|
||||
|
||||
@ -104,6 +107,7 @@ test "parse and render UNIX addresses" {
|
||||
}
|
||||
|
||||
test "resolve DNS" {
|
||||
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
|
||||
if (builtin.os.tag == .wasi) return error.SkipZigTest;
|
||||
|
||||
if (builtin.os.tag == .windows) {
|
||||
|
||||
@ -399,6 +399,7 @@ test "std.PriorityQueue: fromOwnedSlice trivial case 1" {
|
||||
}
|
||||
|
||||
test "std.PriorityQueue: fromOwnedSlice" {
|
||||
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
|
||||
const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
|
||||
const heap_items = try testing.allocator.dupe(u32, items[0..]);
|
||||
var queue = PQlt.fromOwnedSlice(testing.allocator, heap_items[0..], {});
|
||||
|
||||
@ -160,6 +160,7 @@ pub fn extract(
|
||||
}
|
||||
|
||||
test "vector patterns" {
|
||||
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
|
||||
const base = @Vector(4, u32){ 10, 20, 30, 40 };
|
||||
const other_base = @Vector(4, u32){ 55, 66, 77, 88 };
|
||||
|
||||
|
||||
@ -6876,6 +6876,9 @@ fn asmExpr(
|
||||
const constraint = (try astgen.strLitAsString(constraint_token)).index;
|
||||
const has_arrow = token_tags[symbolic_name + 4] == .arrow;
|
||||
if (has_arrow) {
|
||||
if (output_type_bits != 0) {
|
||||
return astgen.failNode(output_node, "inline assembly allows up to one output value", .{});
|
||||
}
|
||||
output_type_bits |= @as(u32, 1) << @intCast(u5, i);
|
||||
const out_type_node = node_datas[output_node].lhs;
|
||||
const out_type_inst = try typeExpr(gz, scope, out_type_node);
|
||||
@ -6892,7 +6895,7 @@ fn asmExpr(
|
||||
outputs[i] = .{
|
||||
.name = name,
|
||||
.constraint = constraint,
|
||||
.operand = try localVarRef(gz, scope, rl, node, ident_token),
|
||||
.operand = try localVarRef(gz, scope, .ref, node, ident_token),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
106
src/Sema.zig
106
src/Sema.zig
@ -7774,7 +7774,12 @@ fn zirSwitchCapture(
|
||||
}
|
||||
|
||||
switch (operand_ty.zigTypeTag()) {
|
||||
.ErrorSet => return sema.bitCast(block, block.switch_else_err_ty.?, operand, operand_src),
|
||||
.ErrorSet => if (block.switch_else_err_ty) |some| {
|
||||
return sema.bitCast(block, some, operand, operand_src);
|
||||
} else {
|
||||
try block.addUnreachable(operand_src, false);
|
||||
return Air.Inst.Ref.unreachable_value;
|
||||
},
|
||||
else => return operand,
|
||||
}
|
||||
}
|
||||
@ -8194,7 +8199,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
|
||||
);
|
||||
}
|
||||
else_error_ty = Type.@"anyerror";
|
||||
} else {
|
||||
} else else_validation: {
|
||||
var maybe_msg: ?*Module.ErrorMsg = null;
|
||||
errdefer if (maybe_msg) |msg| msg.destroy(sema.gpa);
|
||||
|
||||
@ -8231,6 +8236,27 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
|
||||
}
|
||||
|
||||
if (special_prong == .@"else" and seen_errors.count() == operand_ty.errorSetNames().len) {
|
||||
|
||||
// In order to enable common patterns for generic code allow simple else bodies
|
||||
// else => unreachable,
|
||||
// else => return,
|
||||
// else => |e| return e,
|
||||
// even if all the possible errors were already handled.
|
||||
const tags = sema.code.instructions.items(.tag);
|
||||
for (special.body) |else_inst| switch (tags[else_inst]) {
|
||||
.dbg_block_begin,
|
||||
.dbg_block_end,
|
||||
.dbg_stmt,
|
||||
.dbg_var_val,
|
||||
.switch_capture,
|
||||
.ret_type,
|
||||
.as_node,
|
||||
.ret_node,
|
||||
.@"unreachable",
|
||||
=> {},
|
||||
else => break,
|
||||
} else break :else_validation;
|
||||
|
||||
return sema.fail(
|
||||
block,
|
||||
special_prong_src,
|
||||
@ -11308,43 +11334,40 @@ fn zirAsm(
|
||||
try sema.requireRuntimeBlock(block, src);
|
||||
}
|
||||
|
||||
if (outputs_len > 1) {
|
||||
return sema.fail(block, src, "TODO implement Sema for asm with more than 1 output", .{});
|
||||
}
|
||||
|
||||
var extra_i = extra.end;
|
||||
var output_type_bits = extra.data.output_type_bits;
|
||||
var needed_capacity: usize = @typeInfo(Air.Asm).Struct.fields.len + outputs_len + inputs_len;
|
||||
|
||||
const Output = struct {
|
||||
constraint: []const u8,
|
||||
name: []const u8,
|
||||
ty: Type,
|
||||
};
|
||||
const output: ?Output = if (outputs_len == 0) null else blk: {
|
||||
const ConstraintName = struct { c: []const u8, n: []const u8 };
|
||||
const out_args = try sema.arena.alloc(Air.Inst.Ref, outputs_len);
|
||||
const outputs = try sema.arena.alloc(ConstraintName, outputs_len);
|
||||
var expr_ty = Air.Inst.Ref.void_type;
|
||||
|
||||
for (out_args) |*arg, out_i| {
|
||||
const output = sema.code.extraData(Zir.Inst.Asm.Output, extra_i);
|
||||
extra_i = output.end;
|
||||
|
||||
const is_type = @truncate(u1, output_type_bits) != 0;
|
||||
output_type_bits >>= 1;
|
||||
|
||||
if (!is_type) {
|
||||
return sema.fail(block, src, "TODO implement Sema for asm with non `->` output", .{});
|
||||
if (is_type) {
|
||||
// Indicate the output is the asm instruction return value.
|
||||
arg.* = .none;
|
||||
const out_ty = try sema.resolveType(block, ret_ty_src, output.data.operand);
|
||||
expr_ty = try sema.addType(out_ty);
|
||||
} else {
|
||||
arg.* = try sema.resolveInst(output.data.operand);
|
||||
}
|
||||
|
||||
const constraint = sema.code.nullTerminatedString(output.data.constraint);
|
||||
const name = sema.code.nullTerminatedString(output.data.name);
|
||||
needed_capacity += (constraint.len + name.len + (2 + 3)) / 4;
|
||||
|
||||
break :blk Output{
|
||||
.constraint = constraint,
|
||||
.name = name,
|
||||
.ty = try sema.resolveType(block, ret_ty_src, output.data.operand),
|
||||
};
|
||||
};
|
||||
outputs[out_i] = .{ .c = constraint, .n = name };
|
||||
}
|
||||
|
||||
const args = try sema.arena.alloc(Air.Inst.Ref, inputs_len);
|
||||
const inputs = try sema.arena.alloc(struct { c: []const u8, n: []const u8 }, inputs_len);
|
||||
const inputs = try sema.arena.alloc(ConstraintName, inputs_len);
|
||||
|
||||
for (args) |*arg, arg_i| {
|
||||
const input = sema.code.extraData(Zir.Inst.Asm.Input, extra_i);
|
||||
@ -11379,7 +11402,7 @@ fn zirAsm(
|
||||
const asm_air = try block.addInst(.{
|
||||
.tag = .assembly,
|
||||
.data = .{ .ty_pl = .{
|
||||
.ty = if (output) |o| try sema.addType(o.ty) else Air.Inst.Ref.void_type,
|
||||
.ty = expr_ty,
|
||||
.payload = sema.addExtraAssumeCapacity(Air.Asm{
|
||||
.source_len = @intCast(u32, asm_source.len),
|
||||
.outputs_len = outputs_len,
|
||||
@ -11388,18 +11411,15 @@ fn zirAsm(
|
||||
}),
|
||||
} },
|
||||
});
|
||||
if (output != null) {
|
||||
// Indicate the output is the asm instruction return value.
|
||||
sema.air_extra.appendAssumeCapacity(@enumToInt(Air.Inst.Ref.none));
|
||||
}
|
||||
sema.appendRefsAssumeCapacity(out_args);
|
||||
sema.appendRefsAssumeCapacity(args);
|
||||
if (output) |o| {
|
||||
for (outputs) |o| {
|
||||
const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice());
|
||||
mem.copy(u8, buffer, o.constraint);
|
||||
buffer[o.constraint.len] = 0;
|
||||
mem.copy(u8, buffer[o.constraint.len + 1 ..], o.name);
|
||||
buffer[o.constraint.len + 1 + o.name.len] = 0;
|
||||
sema.air_extra.items.len += (o.constraint.len + o.name.len + (2 + 3)) / 4;
|
||||
mem.copy(u8, buffer, o.c);
|
||||
buffer[o.c.len] = 0;
|
||||
mem.copy(u8, buffer[o.c.len + 1 ..], o.n);
|
||||
buffer[o.c.len + 1 + o.n.len] = 0;
|
||||
sema.air_extra.items.len += (o.c.len + o.n.len + (2 + 3)) / 4;
|
||||
}
|
||||
for (inputs) |input| {
|
||||
const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice());
|
||||
@ -21870,6 +21890,28 @@ fn analyzeIsNonErrComptimeOnly(
|
||||
if (ies.is_anyerror) break :blk;
|
||||
if (ies.errors.count() != 0) break :blk;
|
||||
if (maybe_operand_val == null) {
|
||||
// Try to avoid resolving inferred error set if possible.
|
||||
if (ies.errors.count() != 0) break :blk;
|
||||
if (ies.is_anyerror) break :blk;
|
||||
var it = ies.inferred_error_sets.keyIterator();
|
||||
while (it.next()) |other_error_set_ptr| {
|
||||
const other_ies: *Module.Fn.InferredErrorSet = other_error_set_ptr.*;
|
||||
if (ies == other_ies) continue;
|
||||
try sema.resolveInferredErrorSet(block, src, other_ies);
|
||||
if (other_ies.is_anyerror) {
|
||||
ies.is_anyerror = true;
|
||||
ies.is_resolved = true;
|
||||
break :blk;
|
||||
}
|
||||
|
||||
if (other_ies.errors.count() != 0) break :blk;
|
||||
}
|
||||
if (ies.func == sema.owner_func) {
|
||||
// We're checking the inferred errorset of the current function and none of
|
||||
// its child inferred error sets contained any errors meaning that any value
|
||||
// so far with this type can't contain errors either.
|
||||
return Air.Inst.Ref.bool_true;
|
||||
}
|
||||
try sema.resolveInferredErrorSet(block, src, ies);
|
||||
if (ies.is_anyerror) break :blk;
|
||||
if (ies.errors.count() == 0) return Air.Inst.Ref.bool_true;
|
||||
|
||||
@ -5012,7 +5012,7 @@ pub const FuncGen = struct {
|
||||
const compiler_rt_operand_abbrev = compilerRtFloatAbbrev(operand_bits);
|
||||
|
||||
const compiler_rt_dest_abbrev = compilerRtIntAbbrev(rt_int_bits);
|
||||
const sign_prefix = if (dest_scalar_ty.isSignedInt()) "" else "un";
|
||||
const sign_prefix = if (dest_scalar_ty.isSignedInt()) "" else "uns";
|
||||
|
||||
var fn_name_buf: [64]u8 = undefined;
|
||||
const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__fix{s}{s}f{s}i", .{
|
||||
@ -5435,10 +5435,6 @@ pub const FuncGen = struct {
|
||||
const inputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);
|
||||
extra_i += inputs.len;
|
||||
|
||||
if (outputs.len > 1) {
|
||||
return self.todo("implement llvm codegen for asm with more than 1 output", .{});
|
||||
}
|
||||
|
||||
var llvm_constraints: std.ArrayListUnmanaged(u8) = .{};
|
||||
defer llvm_constraints.deinit(self.gpa);
|
||||
|
||||
@ -5446,7 +5442,10 @@ pub const FuncGen = struct {
|
||||
defer arena_allocator.deinit();
|
||||
const arena = arena_allocator.allocator();
|
||||
|
||||
const llvm_params_len = inputs.len;
|
||||
const return_count: u8 = for (outputs) |output| {
|
||||
if (output == .none) break 1;
|
||||
} else 0;
|
||||
const llvm_params_len = inputs.len + outputs.len - return_count;
|
||||
const llvm_param_types = try arena.alloc(*const llvm.Type, llvm_params_len);
|
||||
const llvm_param_values = try arena.alloc(*const llvm.Value, llvm_params_len);
|
||||
var llvm_param_i: usize = 0;
|
||||
@ -5456,9 +5455,6 @@ pub const FuncGen = struct {
|
||||
try name_map.ensureUnusedCapacity(arena, outputs.len + inputs.len);
|
||||
|
||||
for (outputs) |output| {
|
||||
if (output != .none) {
|
||||
return self.todo("implement inline asm with non-returned output", .{});
|
||||
}
|
||||
const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
|
||||
const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);
|
||||
const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
|
||||
@ -5471,6 +5467,15 @@ pub const FuncGen = struct {
|
||||
llvm_constraints.appendAssumeCapacity(',');
|
||||
}
|
||||
llvm_constraints.appendAssumeCapacity('=');
|
||||
if (output != .none) {
|
||||
try llvm_constraints.ensureUnusedCapacity(self.gpa, llvm_constraints.capacity + 1);
|
||||
llvm_constraints.appendAssumeCapacity('*');
|
||||
|
||||
const output_inst = try self.resolveInst(output);
|
||||
llvm_param_values[llvm_param_i] = output_inst;
|
||||
llvm_param_types[llvm_param_i] = output_inst.typeOf();
|
||||
llvm_param_i += 1;
|
||||
}
|
||||
llvm_constraints.appendSliceAssumeCapacity(constraint[1..]);
|
||||
|
||||
name_map.putAssumeCapacityNoClobber(name, {});
|
||||
@ -9284,7 +9289,7 @@ fn needDbgVarWorkaround(dg: *DeclGen, ty: Type) bool {
|
||||
}
|
||||
|
||||
fn compilerRtIntBits(bits: u16) u16 {
|
||||
inline for (.{ 8, 16, 32, 64, 128 }) |b| {
|
||||
inline for (.{ 32, 64, 128 }) |b| {
|
||||
if (bits <= b) {
|
||||
return b;
|
||||
}
|
||||
|
||||
@ -754,3 +754,45 @@ test "error union payload is properly aligned" {
|
||||
const blk = S.foo() catch unreachable;
|
||||
if (blk.a != 1) unreachable;
|
||||
}
|
||||
|
||||
test "ret_ptr doesn't cause own inferred error set to be resolved" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn foo() !void {}
|
||||
|
||||
fn doTheTest() !void {
|
||||
errdefer @compileError("bad");
|
||||
|
||||
return try @This().foo();
|
||||
}
|
||||
};
|
||||
try S.doTheTest();
|
||||
}
|
||||
|
||||
test "simple else prong allowed even when all errors handled" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn foo() !u8 {
|
||||
return error.Foo;
|
||||
}
|
||||
};
|
||||
var value = S.foo() catch |err| switch (err) {
|
||||
error.Foo => 255,
|
||||
else => |e| return e,
|
||||
};
|
||||
try expect(value == 255);
|
||||
value = S.foo() catch |err| switch (err) {
|
||||
error.Foo => 255,
|
||||
else => unreachable,
|
||||
};
|
||||
try expect(value == 255);
|
||||
value = S.foo() catch |err| switch (err) {
|
||||
error.Foo => 255,
|
||||
else => return,
|
||||
};
|
||||
try expect(value == 255);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user