Commit 9afa974183
Changed files (7)
src
src/codegen/llvm.zig
@@ -3267,21 +3267,28 @@ pub const DeclGen = struct {
return llvm_ty.constInt(kv.value, .False);
},
.error_union => |error_union| {
+ const err_tv: TypedValue = switch (error_union.val) {
+ .err_name => |err_name| .{
+ .ty = tv.ty.errorUnionSet(mod),
+ .val = (try mod.intern(.{ .err = .{
+ .ty = tv.ty.errorUnionSet(mod).toIntern(),
+ .name = err_name,
+ } })).toValue(),
+ },
+ .payload => .{
+ .ty = Type.err_int,
+ .val = try mod.intValue(Type.err_int, 0),
+ },
+ };
const payload_type = tv.ty.errorUnionPayload(mod);
- const is_pl = tv.val.errorUnionIsPayload(mod);
-
if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
// We use the error type directly as the type.
- const err_val = if (!is_pl) tv.val else try mod.intValue(Type.err_int, 0);
- return dg.lowerValue(.{ .ty = Type.anyerror, .val = err_val });
+ return dg.lowerValue(err_tv);
}
const payload_align = payload_type.abiAlignment(mod);
- const error_align = Type.anyerror.abiAlignment(mod);
- const llvm_error_value = try dg.lowerValue(.{
- .ty = Type.anyerror,
- .val = if (is_pl) try mod.intValue(Type.err_int, 0) else tv.val,
- });
+ const error_align = err_tv.ty.abiAlignment(mod);
+ const llvm_error_value = try dg.lowerValue(err_tv);
const llvm_payload_value = try dg.lowerValue(.{
.ty = payload_type,
.val = switch (error_union.val) {
src/Liveness/Verify.zig
@@ -61,10 +61,10 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
.work_item_id,
.work_group_size,
.work_group_id,
- => try self.verifyInst(inst, .{ .none, .none, .none }),
+ => try self.verifyInstOperands(inst, .{ .none, .none, .none }),
.trap, .unreach => {
- try self.verifyInst(inst, .{ .none, .none, .none });
+ try self.verifyInstOperands(inst, .{ .none, .none, .none });
// This instruction terminates the function, so everything should be dead
if (self.live.count() > 0) return invalid("%{}: instructions still alive", .{inst});
},
@@ -113,7 +113,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
.c_va_copy,
=> {
const ty_op = data[inst].ty_op;
- try self.verifyInst(inst, .{ ty_op.operand, .none, .none });
+ try self.verifyInstOperands(inst, .{ ty_op.operand, .none, .none });
},
.is_null,
.is_non_null,
@@ -149,13 +149,13 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
.c_va_end,
=> {
const un_op = data[inst].un_op;
- try self.verifyInst(inst, .{ un_op, .none, .none });
+ try self.verifyInstOperands(inst, .{ un_op, .none, .none });
},
.ret,
.ret_load,
=> {
const un_op = data[inst].un_op;
- try self.verifyInst(inst, .{ un_op, .none, .none });
+ try self.verifyInstOperands(inst, .{ un_op, .none, .none });
// This instruction terminates the function, so everything should be dead
if (self.live.count() > 0) return invalid("%{}: instructions still alive", .{inst});
},
@@ -164,36 +164,36 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
.wasm_memory_grow,
=> {
const pl_op = data[inst].pl_op;
- try self.verifyInst(inst, .{ pl_op.operand, .none, .none });
+ try self.verifyInstOperands(inst, .{ pl_op.operand, .none, .none });
},
.prefetch => {
const prefetch = data[inst].prefetch;
- try self.verifyInst(inst, .{ prefetch.ptr, .none, .none });
+ try self.verifyInstOperands(inst, .{ prefetch.ptr, .none, .none });
},
.reduce,
.reduce_optimized,
=> {
const reduce = data[inst].reduce;
- try self.verifyInst(inst, .{ reduce.operand, .none, .none });
+ try self.verifyInstOperands(inst, .{ reduce.operand, .none, .none });
},
.union_init => {
const ty_pl = data[inst].ty_pl;
const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
- try self.verifyInst(inst, .{ extra.init, .none, .none });
+ try self.verifyInstOperands(inst, .{ extra.init, .none, .none });
},
.struct_field_ptr, .struct_field_val => {
const ty_pl = data[inst].ty_pl;
const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;
- try self.verifyInst(inst, .{ extra.struct_operand, .none, .none });
+ try self.verifyInstOperands(inst, .{ extra.struct_operand, .none, .none });
},
.field_parent_ptr => {
const ty_pl = data[inst].ty_pl;
const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
- try self.verifyInst(inst, .{ extra.field_ptr, .none, .none });
+ try self.verifyInstOperands(inst, .{ extra.field_ptr, .none, .none });
},
.atomic_load => {
const atomic_load = data[inst].atomic_load;
- try self.verifyInst(inst, .{ atomic_load.ptr, .none, .none });
+ try self.verifyInstOperands(inst, .{ atomic_load.ptr, .none, .none });
},
// binary
@@ -263,7 +263,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
.memcpy,
=> {
const bin_op = data[inst].bin_op;
- try self.verifyInst(inst, .{ bin_op.lhs, bin_op.rhs, .none });
+ try self.verifyInstOperands(inst, .{ bin_op.lhs, bin_op.rhs, .none });
},
.add_with_overflow,
.sub_with_overflow,
@@ -277,48 +277,48 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
=> {
const ty_pl = data[inst].ty_pl;
const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
- try self.verifyInst(inst, .{ extra.lhs, extra.rhs, .none });
+ try self.verifyInstOperands(inst, .{ extra.lhs, extra.rhs, .none });
},
.shuffle => {
const ty_pl = data[inst].ty_pl;
const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;
- try self.verifyInst(inst, .{ extra.a, extra.b, .none });
+ try self.verifyInstOperands(inst, .{ extra.a, extra.b, .none });
},
.cmp_vector,
.cmp_vector_optimized,
=> {
const ty_pl = data[inst].ty_pl;
const extra = self.air.extraData(Air.VectorCmp, ty_pl.payload).data;
- try self.verifyInst(inst, .{ extra.lhs, extra.rhs, .none });
+ try self.verifyInstOperands(inst, .{ extra.lhs, extra.rhs, .none });
},
.atomic_rmw => {
const pl_op = data[inst].pl_op;
const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data;
- try self.verifyInst(inst, .{ pl_op.operand, extra.operand, .none });
+ try self.verifyInstOperands(inst, .{ pl_op.operand, extra.operand, .none });
},
// ternary
.select => {
const pl_op = data[inst].pl_op;
const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
- try self.verifyInst(inst, .{ pl_op.operand, extra.lhs, extra.rhs });
+ try self.verifyInstOperands(inst, .{ pl_op.operand, extra.lhs, extra.rhs });
},
.mul_add => {
const pl_op = data[inst].pl_op;
const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
- try self.verifyInst(inst, .{ extra.lhs, extra.rhs, pl_op.operand });
+ try self.verifyInstOperands(inst, .{ extra.lhs, extra.rhs, pl_op.operand });
},
.vector_store_elem => {
const vector_store_elem = data[inst].vector_store_elem;
const extra = self.air.extraData(Air.Bin, vector_store_elem.payload).data;
- try self.verifyInst(inst, .{ vector_store_elem.vector_ptr, extra.lhs, extra.rhs });
+ try self.verifyInstOperands(inst, .{ vector_store_elem.vector_ptr, extra.lhs, extra.rhs });
},
.cmpxchg_strong,
.cmpxchg_weak,
=> {
const ty_pl = data[inst].ty_pl;
const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
- try self.verifyInst(inst, .{ extra.ptr, extra.expected_value, extra.new_value });
+ try self.verifyInstOperands(inst, .{ extra.ptr, extra.expected_value, extra.new_value });
},
// big tombs
@@ -332,7 +332,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
for (elements) |element| {
try self.verifyOperand(inst, element, bt.feed());
}
- try self.verifyInst(inst, .{ .none, .none, .none });
+ try self.verifyInst(inst);
},
.call, .call_always_tail, .call_never_tail, .call_never_inline => {
const pl_op = data[inst].pl_op;
@@ -347,7 +347,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
for (args) |arg| {
try self.verifyOperand(inst, arg, bt.feed());
}
- try self.verifyInst(inst, .{ .none, .none, .none });
+ try self.verifyInst(inst);
},
.assembly => {
const ty_pl = data[inst].ty_pl;
@@ -373,7 +373,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
for (inputs) |input| {
try self.verifyOperand(inst, input, bt.feed());
}
- try self.verifyInst(inst, .{ .none, .none, .none });
+ try self.verifyInst(inst);
},
// control flow
@@ -397,7 +397,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
for (cond_br_liveness.then_deaths) |death| try self.verifyDeath(inst, death);
- try self.verifyInst(inst, .{ .none, .none, .none });
+ try self.verifyInst(inst);
},
.try_ptr => {
const ty_pl = data[inst].ty_pl;
@@ -419,7 +419,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
for (cond_br_liveness.then_deaths) |death| try self.verifyDeath(inst, death);
- try self.verifyInst(inst, .{ .none, .none, .none });
+ try self.verifyInst(inst);
},
.br => {
const br = data[inst].br;
@@ -431,7 +431,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
} else {
gop.value_ptr.* = try self.live.clone(self.gpa);
}
- try self.verifyInst(inst, .{ .none, .none, .none });
+ try self.verifyInst(inst);
},
.block => {
const ty_pl = data[inst].ty_pl;
@@ -462,7 +462,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
try self.verifyMatchingLiveness(inst, live);
}
- try self.verifyInst(inst, .{ .none, .none, .none });
+ try self.verifyInstOperands(inst, .{ .none, .none, .none });
},
.loop => {
const ty_pl = data[inst].ty_pl;
@@ -477,7 +477,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
// The same stuff should be alive after the loop as before it
try self.verifyMatchingLiveness(inst, live);
- try self.verifyInst(inst, .{ .none, .none, .none });
+ try self.verifyInstOperands(inst, .{ .none, .none, .none });
},
.cond_br => {
const pl_op = data[inst].pl_op;
@@ -500,7 +500,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
for (cond_br_liveness.else_deaths) |death| try self.verifyDeath(inst, death);
try self.verifyBody(else_body);
- try self.verifyInst(inst, .{ .none, .none, .none });
+ try self.verifyInst(inst);
},
.switch_br => {
const pl_op = data[inst].pl_op;
@@ -544,7 +544,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
try self.verifyBody(else_body);
}
- try self.verifyInst(inst, .{ .none, .none, .none });
+ try self.verifyInst(inst);
},
}
}
@@ -570,7 +570,7 @@ fn verifyOperand(self: *Verify, inst: Air.Inst.Index, op_ref: Air.Inst.Ref, dies
}
}
-fn verifyInst(
+fn verifyInstOperands(
self: *Verify,
inst: Air.Inst.Index,
operands: [Liveness.bpi - 1]Air.Inst.Ref,
@@ -579,6 +579,10 @@ fn verifyInst(
const dies = self.liveness.operandDies(inst, @intCast(Liveness.OperandInt, operand_index));
try self.verifyOperand(inst, operand, dies);
}
+ try self.verifyInst(inst);
+}
+
+fn verifyInst(self: *Verify, inst: Air.Inst.Index) Error!void {
if (self.air.instructions.items(.tag)[inst] == .interned) return;
if (self.liveness.isUnused(inst)) {
assert(!self.live.contains(inst));
src/InternPool.zig
@@ -2298,7 +2298,7 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
ip.* = undefined;
}
-pub fn indexToKey(ip: InternPool, index: Index) Key {
+pub fn indexToKey(ip: *const InternPool, index: Index) Key {
assert(index != .none);
const item = ip.items.get(@enumToInt(index));
const data = item.data;
@@ -2361,7 +2361,7 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
.type_slice => {
const ptr_type_index = @intToEnum(Index, data);
- var result = indexToKey(ip, ptr_type_index).ptr_type;
+ var result = ip.indexToKey(ptr_type_index).ptr_type;
result.size = .Slice;
return .{ .ptr_type = result };
},
@@ -2454,9 +2454,9 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
.values_map = .none,
} };
},
- .type_enum_explicit => indexToKeyEnum(ip, data, .explicit),
- .type_enum_nonexhaustive => indexToKeyEnum(ip, data, .nonexhaustive),
- .type_function => .{ .func_type = indexToKeyFuncType(ip, data) },
+ .type_enum_explicit => ip.indexToKeyEnum(data, .explicit),
+ .type_enum_nonexhaustive => ip.indexToKeyEnum(data, .nonexhaustive),
+ .type_function => .{ .func_type = ip.indexToKeyFuncType(data) },
.undef => .{ .undef = @intToEnum(Index, data) },
.runtime_value => {
@@ -2591,8 +2591,8 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
.ty = .comptime_int_type,
.storage = .{ .i64 = @bitCast(i32, data) },
} },
- .int_positive => indexToKeyBigInt(ip, data, true),
- .int_negative => indexToKeyBigInt(ip, data, false),
+ .int_positive => ip.indexToKeyBigInt(data, true),
+ .int_negative => ip.indexToKeyBigInt(data, false),
.int_small => {
const info = ip.extraData(IntSmall, data);
return .{ .int = .{
@@ -3430,22 +3430,25 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
.data = try ip.addExtra(gpa, err),
}),
- .error_union => |error_union| ip.items.appendAssumeCapacity(switch (error_union.val) {
- .err_name => |err_name| .{
- .tag = .error_union_error,
- .data = try ip.addExtra(gpa, Key.Error{
- .ty = error_union.ty,
- .name = err_name,
- }),
- },
- .payload => |payload| .{
- .tag = .error_union_payload,
- .data = try ip.addExtra(gpa, TypeValue{
- .ty = error_union.ty,
- .val = payload,
- }),
- },
- }),
+ .error_union => |error_union| {
+ assert(ip.indexToKey(error_union.ty) == .error_union_type);
+ ip.items.appendAssumeCapacity(switch (error_union.val) {
+ .err_name => |err_name| .{
+ .tag = .error_union_error,
+ .data = try ip.addExtra(gpa, Key.Error{
+ .ty = error_union.ty,
+ .name = err_name,
+ }),
+ },
+ .payload => |payload| .{
+ .tag = .error_union_payload,
+ .data = try ip.addExtra(gpa, TypeValue{
+ .ty = error_union.ty,
+ .val = payload,
+ }),
+ },
+ });
+ },
.enum_literal => |enum_literal| ip.items.appendAssumeCapacity(.{
.tag = .enum_literal,
@@ -4191,6 +4194,7 @@ pub fn sliceLen(ip: InternPool, i: Index) Index {
/// * ptr <=> ptr
/// * null_value => opt
/// * payload => opt
+/// * error set <=> error set
pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index {
const old_ty = ip.typeOf(val);
if (old_ty == new_ty) return val;
@@ -4230,6 +4234,13 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
} }),
else => {},
},
+ .err => |err| switch (ip.indexToKey(new_ty)) {
+ .error_set_type, .inferred_error_set_type => return ip.get(gpa, .{ .err = .{
+ .ty = new_ty,
+ .name = err.name,
+ } }),
+ else => {},
+ },
else => {},
}
switch (ip.indexToKey(new_ty)) {
src/print_air.zig
@@ -703,7 +703,7 @@ const Writer = struct {
const pl_op = w.air.instructions.items(.data)[inst].pl_op;
try w.writeOperand(s, inst, 0, pl_op.operand);
const name = w.air.nullTerminatedString(pl_op.payload);
- try s.print(", {s}", .{name});
+ try s.print(", \"{}\"", .{std.zig.fmtEscapes(name)});
}
fn writeCall(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
src/Sema.zig
@@ -16687,7 +16687,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
const new_decl_ty = try mod.arrayType(.{
.len = bytes.len,
.child = .u8_type,
- .sentinel = .zero_u8,
});
const new_decl = try anon_decl.finish(
new_decl_ty,
@@ -16698,7 +16697,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
0, // default alignment
);
break :v try mod.intern(.{ .ptr = .{
- .ty = .slice_const_u8_sentinel_0_type,
+ .ty = .slice_const_u8_type,
.addr = .{ .decl = new_decl },
.len = (try mod.intValue(Type.usize, bytes.len)).toIntern(),
} });
@@ -23991,7 +23990,6 @@ fn panicWithMsg(
msg_inst: Air.Inst.Ref,
) !void {
const mod = sema.mod;
- const arena = sema.arena;
if (!mod.backendSupportsFeature(.panic_fn)) {
_ = try block.addNoOp(.trap);
@@ -24001,16 +23999,22 @@ fn panicWithMsg(
const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
const target = mod.getTarget();
- const ptr_stack_trace_ty = try Type.ptr(arena, mod, .{
- .pointee_type = stack_trace_ty,
- .@"addrspace" = target_util.defaultAddressSpace(target, .global_constant), // TODO might need a place that is more dynamic
+ const ptr_stack_trace_ty = try mod.ptrType(.{
+ .elem_type = stack_trace_ty.toIntern(),
+ .address_space = target_util.defaultAddressSpace(target, .global_constant), // TODO might need a place that is more dynamic
});
- const null_stack_trace = try sema.addConstant(
- try Type.optional(arena, ptr_stack_trace_ty, mod),
- Value.null,
- );
- const args: [3]Air.Inst.Ref = .{ msg_inst, null_stack_trace, .null_value };
- try sema.callBuiltin(block, panic_fn, .auto, &args);
+ const opt_ptr_stack_trace_ty = try mod.optionalType(ptr_stack_trace_ty.toIntern());
+ const null_stack_trace = try sema.addConstant(opt_ptr_stack_trace_ty, (try mod.intern(.{ .opt = .{
+ .ty = opt_ptr_stack_trace_ty.toIntern(),
+ .val = .none,
+ } })).toValue());
+
+ const opt_usize_ty = try mod.optionalType(.usize_type);
+ const null_ret_addr = try sema.addConstant(opt_usize_ty, (try mod.intern(.{ .opt = .{
+ .ty = opt_usize_ty.toIntern(),
+ .val = .none,
+ } })).toValue());
+ try sema.callBuiltin(block, panic_fn, .auto, &.{ msg_inst, null_stack_trace, null_ret_addr });
}
fn panicUnwrapError(
@@ -29395,13 +29399,10 @@ fn refValue(sema: *Sema, block: *Block, ty: Type, val: Value) !Value {
fn optRefValue(sema: *Sema, block: *Block, ty: Type, opt_val: ?Value) !Value {
const mod = sema.mod;
- const val = opt_val orelse return Value.null;
- const ptr_val = try sema.refValue(block, ty, val);
- const result = try mod.intern(.{ .opt = .{
- .ty = (try mod.optionalType((try mod.singleConstPtrType(ty)).toIntern())).toIntern(),
- .val = ptr_val.toIntern(),
- } });
- return result.toValue();
+ return (try mod.intern(.{ .opt = .{
+ .ty = (try mod.optionalType((try mod.singleConstPtrType(Type.anyopaque)).toIntern())).toIntern(),
+ .val = if (opt_val) |val| (try sema.refValue(block, ty, val)).toIntern() else .none,
+ } })).toValue();
}
fn analyzeDeclRef(sema: *Sema, decl_index: Decl.Index) CompileError!Air.Inst.Ref {
@@ -30603,7 +30604,7 @@ fn wrapErrorUnionPayload(
if (try sema.resolveMaybeUndefVal(coerced)) |val| {
return sema.addConstant(dest_ty, (try mod.intern(.{ .error_union = .{
.ty = dest_ty.toIntern(),
- .val = .{ .payload = val.toIntern() },
+ .val = .{ .payload = try val.intern(dest_payload_ty, mod) },
} })).toValue());
}
try sema.requireRuntimeBlock(block, inst_src, null);
@@ -30647,7 +30648,12 @@ fn wrapErrorUnionSet(
else => unreachable,
},
}
- return sema.addConstant(dest_ty, val);
+ return sema.addConstant(dest_ty, (try mod.intern(.{ .error_union = .{
+ .ty = dest_ty.toIntern(),
+ .val = .{
+ .err_name = mod.intern_pool.indexToKey(try val.intern(dest_err_set_ty, mod)).err.name,
+ },
+ } })).toValue());
}
try sema.requireRuntimeBlock(block, inst_src, null);
@@ -33325,7 +33331,7 @@ fn addIntUnsigned(sema: *Sema, ty: Type, int: u64) CompileError!Air.Inst.Ref {
}
fn addConstUndef(sema: *Sema, ty: Type) CompileError!Air.Inst.Ref {
- return sema.addConstant(ty, Value.undef);
+ return sema.addConstant(ty, (try sema.mod.intern(.{ .undef = ty.toIntern() })).toValue());
}
pub fn addConstant(sema: *Sema, ty: Type, val: Value) SemaError!Air.Inst.Ref {
src/value.zig
@@ -347,6 +347,43 @@ pub const Value = struct {
pub fn intern(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index {
if (val.ip_index != .none) return mod.intern_pool.getCoerced(mod.gpa, val.toIntern(), ty.toIntern());
switch (val.tag()) {
+ .eu_payload => {
+ const pl = val.castTag(.eu_payload).?.data;
+ return mod.intern(.{ .error_union = .{
+ .ty = ty.toIntern(),
+ .val = .{ .payload = try pl.intern(ty.errorUnionPayload(mod), mod) },
+ } });
+ },
+ .opt_payload => {
+ const pl = val.castTag(.opt_payload).?.data;
+ return mod.intern(.{ .opt = .{
+ .ty = ty.toIntern(),
+ .val = try pl.intern(ty.optionalChild(mod), mod),
+ } });
+ },
+ .slice => {
+ const pl = val.castTag(.slice).?.data;
+ const ptr = try pl.ptr.intern(ty.optionalChild(mod), mod);
+ var ptr_key = mod.intern_pool.indexToKey(ptr).ptr;
+ assert(ptr_key.len == .none);
+ ptr_key.ty = ty.toIntern();
+ ptr_key.len = try pl.len.intern(Type.usize, mod);
+ return mod.intern(.{ .ptr = ptr_key });
+ },
+ .bytes => {
+ const pl = val.castTag(.bytes).?.data;
+ return mod.intern(.{ .aggregate = .{
+ .ty = ty.toIntern(),
+ .storage = .{ .bytes = pl },
+ } });
+ },
+ .repeated => {
+ const pl = val.castTag(.repeated).?.data;
+ return mod.intern(.{ .aggregate = .{
+ .ty = ty.toIntern(),
+ .storage = .{ .repeated_elem = try pl.intern(ty.childType(mod), mod) },
+ } });
+ },
.aggregate => {
const old_elems = val.castTag(.aggregate).?.data;
const new_elems = try mod.gpa.alloc(InternPool.Index, old_elems.len);
@@ -372,24 +409,74 @@ pub const Value = struct {
.val = try pl.val.intern(ty.unionFieldType(pl.tag, mod), mod),
} });
},
- else => unreachable,
}
}
pub fn unintern(val: Value, arena: Allocator, mod: *Module) Allocator.Error!Value {
- if (val.ip_index == .none) return val;
- switch (mod.intern_pool.indexToKey(val.toIntern())) {
+ return if (val.ip_index == .none) val else switch (mod.intern_pool.indexToKey(val.toIntern())) {
+ .int_type,
+ .ptr_type,
+ .array_type,
+ .vector_type,
+ .opt_type,
+ .anyframe_type,
+ .error_union_type,
+ .simple_type,
+ .struct_type,
+ .anon_struct_type,
+ .union_type,
+ .opaque_type,
+ .enum_type,
+ .func_type,
+ .error_set_type,
+ .inferred_error_set_type,
+
+ .undef,
+ .runtime_value,
+ .simple_value,
+ .variable,
+ .extern_func,
+ .func,
+ .int,
+ .err,
+ .enum_literal,
+ .enum_tag,
+ .float,
+ => val,
+
+ .error_union => |error_union| switch (error_union.val) {
+ .err_name => val,
+ .payload => |payload| Tag.eu_payload.create(arena, payload.toValue()),
+ },
+
+ .ptr => |ptr| switch (ptr.len) {
+ .none => val,
+ else => |len| Tag.slice.create(arena, .{
+ .ptr = val.slicePtr(mod),
+ .len = len.toValue(),
+ }),
+ },
+
+ .opt => |opt| switch (opt.val) {
+ .none => val,
+ else => |payload| Tag.opt_payload.create(arena, payload.toValue()),
+ },
+
.aggregate => |aggregate| switch (aggregate.storage) {
- .bytes => |bytes| return Tag.bytes.create(arena, try arena.dupe(u8, bytes)),
+ .bytes => |bytes| Tag.bytes.create(arena, try arena.dupe(u8, bytes)),
.elems => |old_elems| {
const new_elems = try arena.alloc(Value, old_elems.len);
for (new_elems, old_elems) |*new_elem, old_elem| new_elem.* = old_elem.toValue();
return Tag.aggregate.create(arena, new_elems);
},
- .repeated_elem => |elem| return Tag.repeated.create(arena, elem.toValue()),
+ .repeated_elem => |elem| Tag.repeated.create(arena, elem.toValue()),
},
- else => return val,
- }
+
+ .un => |un| Tag.@"union".create(arena, .{
+ .tag = un.tag.toValue(),
+ .val = un.val.toValue(),
+ }),
+ };
}
pub fn toIntern(val: Value) InternPool.Index {
@@ -1896,7 +1983,7 @@ pub const Value = struct {
/// Returns true if a Value is backed by a variable
pub fn isVariable(val: Value, mod: *Module) bool {
- return switch (mod.intern_pool.indexToKey(val.toIntern())) {
+ return val.ip_index != .none and switch (mod.intern_pool.indexToKey(val.toIntern())) {
.variable => true,
.ptr => |ptr| switch (ptr.addr) {
.decl => |decl_index| {
@@ -1919,28 +2006,25 @@ pub const Value = struct {
}
pub fn isPtrToThreadLocal(val: Value, mod: *Module) bool {
- return switch (val.ip_index) {
- .none => false,
- else => switch (mod.intern_pool.indexToKey(val.toIntern())) {
- .variable => |variable| variable.is_threadlocal,
- .ptr => |ptr| switch (ptr.addr) {
- .decl => |decl_index| {
- const decl = mod.declPtr(decl_index);
- assert(decl.has_tv);
- return decl.val.isPtrToThreadLocal(mod);
- },
- .mut_decl => |mut_decl| {
- const decl = mod.declPtr(mut_decl.decl);
- assert(decl.has_tv);
- return decl.val.isPtrToThreadLocal(mod);
- },
- .int => false,
- .eu_payload, .opt_payload => |base_ptr| base_ptr.toValue().isPtrToThreadLocal(mod),
- .comptime_field => |comptime_field| comptime_field.toValue().isPtrToThreadLocal(mod),
- .elem, .field => |base_index| base_index.base.toValue().isPtrToThreadLocal(mod),
+ return val.ip_index != .none and switch (mod.intern_pool.indexToKey(val.toIntern())) {
+ .variable => |variable| variable.is_threadlocal,
+ .ptr => |ptr| switch (ptr.addr) {
+ .decl => |decl_index| {
+ const decl = mod.declPtr(decl_index);
+ assert(decl.has_tv);
+ return decl.val.isPtrToThreadLocal(mod);
},
- else => false,
+ .mut_decl => |mut_decl| {
+ const decl = mod.declPtr(mut_decl.decl);
+ assert(decl.has_tv);
+ return decl.val.isPtrToThreadLocal(mod);
+ },
+ .int => false,
+ .eu_payload, .opt_payload => |base_ptr| base_ptr.toValue().isPtrToThreadLocal(mod),
+ .comptime_field => |comptime_field| comptime_field.toValue().isPtrToThreadLocal(mod),
+ .elem, .field => |base_index| base_index.base.toValue().isPtrToThreadLocal(mod),
},
+ else => false,
};
}
tools/lldb_pretty_printers.py
@@ -681,6 +681,7 @@ def __lldb_init_module(debugger, _=None):
add(debugger, category='zig.stage2', regex=True, type=MultiArrayList_Entry('Air\\.Inst'), identifier='TagAndPayload', synth=True, inline_children=True, summary=True)
add(debugger, category='zig.stage2', regex=True, type='^Air\\.Inst\\.Data\\.Data__struct_[1-9][0-9]*$', inline_children=True, summary=True)
add(debugger, category='zig.stage2', type='Module.Decl::Module.Decl.Index', synth=True)
+ add(debugger, category='zig.stage2', type='Module.LazySrcLoc', identifier='zig_TaggedUnion', synth=True)
add(debugger, category='zig.stage2', type='InternPool.Index', synth=True)
add(debugger, category='zig.stage2', type='InternPool.Key', identifier='zig_TaggedUnion', synth=True)
add(debugger, category='zig.stage2', type='InternPool.Key.Int.Storage', identifier='zig_TaggedUnion', synth=True)