Commit 85c69c5194
Changed files (16)
src
arch
link
src/arch/aarch64/abi.zig
@@ -52,7 +52,7 @@ pub fn classifyType(ty: Type, mod: *const Module) Class {
return .byval;
},
.Pointer => {
- std.debug.assert(!ty.isSlice());
+ std.debug.assert(!ty.isSlice(mod));
return .byval;
},
.ErrorUnion,
src/arch/arm/abi.zig
@@ -94,7 +94,7 @@ pub fn classifyType(ty: Type, mod: *const Module, ctx: Context) Class {
return .byval;
},
.Pointer => {
- assert(!ty.isSlice());
+ assert(!ty.isSlice(mod));
return .byval;
},
.ErrorUnion,
src/arch/riscv64/abi.zig
@@ -52,7 +52,7 @@ pub fn classifyType(ty: Type, mod: *const Module) Class {
return .byval;
},
.Pointer => {
- std.debug.assert(!ty.isSlice());
+ std.debug.assert(!ty.isSlice(mod));
return .byval;
},
.ErrorUnion,
src/arch/wasm/abi.zig
@@ -60,7 +60,7 @@ pub fn classifyType(ty: Type, mod: *const Module) [2]Class {
return direct;
},
.Pointer => {
- std.debug.assert(!ty.isSlice());
+ std.debug.assert(!ty.isSlice(mod));
return direct;
},
.Union => {
src/arch/wasm/CodeGen.zig
@@ -1773,7 +1773,7 @@ fn isByRef(ty: Type, mod: *const Module) bool {
},
.Pointer => {
// Slices act like struct and will be passed by reference
- if (ty.isSlice()) return true;
+ if (ty.isSlice(mod)) return true;
return false;
},
}
@@ -2396,7 +2396,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
},
},
.Pointer => {
- if (ty.isSlice()) {
+ if (ty.isSlice(mod)) {
// store pointer first
// lower it to the stack so we do not have to store rhs into a local first
try func.emitWValue(lhs);
@@ -3010,11 +3010,11 @@ fn lowerParentPtrDecl(func: *CodeGen, ptr_val: Value, decl_index: Module.Decl.In
}
fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: Module.Decl.Index, offset: u32) InnerError!WValue {
- if (tv.ty.isSlice()) {
+ const mod = func.bin_file.base.options.module.?;
+ if (tv.ty.isSlice(mod)) {
return WValue{ .memory = try func.bin_file.lowerUnnamedConst(tv, decl_index) };
}
- const mod = func.bin_file.base.options.module.?;
const decl = mod.declPtr(decl_index);
if (decl.ty.zigTypeTag(mod) != .Fn and !decl.ty.hasRuntimeBitsIgnoreComptime(mod)) {
return WValue{ .imm32 = 0xaaaaaaaa };
@@ -4182,7 +4182,7 @@ fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcod
};
try func.addMemArg(.i32_load8_u, .{ .offset = operand.offset() + offset, .alignment = 1 });
}
- } else if (payload_ty.isSlice()) {
+ } else if (payload_ty.isSlice(mod)) {
switch (func.arch()) {
.wasm32 => try func.addMemArg(.i32_load, .{ .offset = operand.offset(), .alignment = 4 }),
.wasm64 => try func.addMemArg(.i64_load, .{ .offset = operand.offset(), .alignment = 8 }),
@@ -4455,10 +4455,11 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airPtrToInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
+ const mod = func.bin_file.base.options.module.?;
const un_op = func.air.instructions.items(.data)[inst].un_op;
const operand = try func.resolveInst(un_op);
const ptr_ty = func.typeOf(un_op);
- const result = if (ptr_ty.isSlice())
+ const result = if (ptr_ty.isSlice(mod))
try func.slicePtr(operand)
else switch (operand) {
// for stack offset, return a pointer to this offset.
@@ -4479,7 +4480,7 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const elem_size = elem_ty.abiSize(mod);
// load pointer onto the stack
- if (ptr_ty.isSlice()) {
+ if (ptr_ty.isSlice(mod)) {
_ = try func.load(ptr, Type.usize, 0);
} else {
try func.lowerToStack(ptr);
@@ -4518,7 +4519,7 @@ fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const index = try func.resolveInst(bin_op.rhs);
// load pointer onto the stack
- if (ptr_ty.isSlice()) {
+ if (ptr_ty.isSlice(mod)) {
_ = try func.load(ptr, Type.usize, 0);
} else {
try func.lowerToStack(ptr);
@@ -5441,7 +5442,8 @@ fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn sliceOrArrayPtr(func: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue {
- if (ptr_ty.isSlice()) {
+ const mod = func.bin_file.base.options.module.?;
+ if (ptr_ty.isSlice(mod)) {
return func.slicePtr(ptr);
} else {
return ptr;
src/arch/x86_64/CodeGen.zig
@@ -8688,7 +8688,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))
- .{ .off = 0, .ty = if (pl_ty.isSlice()) pl_ty.slicePtrFieldType(&ptr_buf) else pl_ty }
+ .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(&ptr_buf) else pl_ty }
else
.{ .off = @intCast(i32, pl_ty.abiSize(mod)), .ty = Type.bool };
@@ -8781,7 +8781,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)
var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))
- .{ .off = 0, .ty = if (pl_ty.isSlice()) pl_ty.slicePtrFieldType(&ptr_buf) else pl_ty }
+ .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(&ptr_buf) else pl_ty }
else
.{ .off = @intCast(i32, pl_ty.abiSize(mod)), .ty = Type.bool };
src/codegen/c.zig
@@ -556,7 +556,7 @@ pub const DeclGen = struct {
if (decl.val.castTag(.variable)) |var_payload|
try dg.renderFwdDecl(decl_index, var_payload.data);
- if (ty.isSlice()) {
+ if (ty.isSlice(mod)) {
if (location == .StaticInitializer) {
try writer.writeByte('{');
} else {
@@ -603,7 +603,7 @@ pub const DeclGen = struct {
fn renderParentPtr(dg: *DeclGen, writer: anytype, ptr_val: Value, ptr_ty: Type, location: ValueRenderLocation) error{ OutOfMemory, AnalysisFail }!void {
const mod = dg.module;
- if (!ptr_ty.isSlice()) {
+ if (!ptr_ty.isSlice(mod)) {
try writer.writeByte('(');
try dg.renderType(writer, ptr_ty);
try writer.writeByte(')');
@@ -776,7 +776,7 @@ pub const DeclGen = struct {
try dg.renderValue(writer, repr_ty, Value.undef, .FunctionArgument);
return writer.writeByte(')');
},
- .Pointer => if (ty.isSlice()) {
+ .Pointer => if (ty.isSlice(mod)) {
if (!location.isInitializer()) {
try writer.writeByte('(');
try dg.renderType(writer, ty);
@@ -1045,7 +1045,7 @@ pub const DeclGen = struct {
return;
},
.Pointer => switch (val.tag()) {
- .null_value, .zero => if (ty.isSlice()) {
+ .null_value, .zero => if (ty.isSlice(mod)) {
var slice_pl = Value.Payload.Slice{
.base = .{ .tag = .slice },
.data = .{ .ptr = val, .len = Value.undef },
@@ -5073,7 +5073,7 @@ fn airIsNull(
TypedValue{ .ty = optional_ty, .val = Value.null }
else if (payload_ty.zigTypeTag(mod) == .ErrorSet)
TypedValue{ .ty = payload_ty, .val = Value.zero }
- else if (payload_ty.isSlice() and optional_ty.optionalReprIsPayload(mod)) rhs: {
+ else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: {
try writer.writeAll(".ptr");
const slice_ptr_ty = payload_ty.slicePtrFieldType(&slice_ptr_buf);
break :rhs TypedValue{ .ty = slice_ptr_ty, .val = Value.null };
@@ -5864,6 +5864,7 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airPtrToInt(f: *Function, inst: Air.Inst.Index) !CValue {
+ const mod = f.object.dg.module;
const un_op = f.air.instructions.items(.data)[inst].un_op;
const operand = try f.resolveInst(un_op);
@@ -5877,7 +5878,7 @@ fn airPtrToInt(f: *Function, inst: Air.Inst.Index) !CValue {
try writer.writeAll(" = (");
try f.renderType(writer, inst_ty);
try writer.writeByte(')');
- if (operand_ty.isSlice()) {
+ if (operand_ty.isSlice(mod)) {
try f.writeCValueMember(writer, operand, .{ .identifier = "len" });
} else {
try f.writeCValue(writer, operand, .Other);
@@ -6272,7 +6273,8 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
}
fn writeSliceOrPtr(f: *Function, writer: anytype, ptr: CValue, ptr_ty: Type) !void {
- if (ptr_ty.isSlice()) {
+ const mod = f.object.dg.module;
+ if (ptr_ty.isSlice(mod)) {
try f.writeCValueMember(writer, ptr, .{ .identifier = "ptr" });
} else {
try f.writeCValue(writer, ptr, .FunctionArgument);
src/codegen/llvm.zig
@@ -1636,7 +1636,7 @@ pub const Object = struct {
return ptr_di_ty;
}
- if (ty.isSlice()) {
+ if (ty.isSlice(mod)) {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = ty.slicePtrFieldType(&buf);
const len_ty = Type.usize;
@@ -2833,7 +2833,7 @@ pub const DeclGen = struct {
},
.Bool => return dg.context.intType(1),
.Pointer => {
- if (t.isSlice()) {
+ if (t.isSlice(mod)) {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_type = t.slicePtrFieldType(&buf);
@@ -4110,7 +4110,7 @@ pub const DeclGen = struct {
}
},
.Pointer => {
- assert(parent_ty.isSlice());
+ assert(parent_ty.isSlice(mod));
const indices: [2]*llvm.Value = .{
llvm_u32.constInt(0, .False),
llvm_u32.constInt(field_index, .False),
@@ -4184,7 +4184,7 @@ pub const DeclGen = struct {
decl_index: Module.Decl.Index,
) Error!*llvm.Value {
const mod = self.module;
- if (tv.ty.isSlice()) {
+ if (tv.ty.isSlice(mod)) {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = tv.ty.slicePtrFieldType(&buf);
var slice_len: Value.Payload.U64 = .{
@@ -5794,7 +5794,8 @@ pub const FuncGen = struct {
}
fn sliceOrArrayPtr(fg: *FuncGen, ptr: *llvm.Value, ty: Type) *llvm.Value {
- if (ty.isSlice()) {
+ const mod = fg.dg.module;
+ if (ty.isSlice(mod)) {
return fg.builder.buildExtractValue(ptr, 0, "");
} else {
return ptr;
@@ -6669,7 +6670,7 @@ pub const FuncGen = struct {
self.builder.buildLoad(optional_llvm_ty, operand, "")
else
operand;
- if (payload_ty.isSlice()) {
+ if (payload_ty.isSlice(mod)) {
const slice_ptr = self.builder.buildExtractValue(loaded, 0, "");
var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = try self.dg.lowerType(payload_ty.slicePtrFieldType(&slice_buf));
@@ -10864,7 +10865,7 @@ const ParamTypeIterator = struct {
it.zig_index += 1;
it.llvm_index += 1;
var buf: Type.Payload.ElemType = undefined;
- if (ty.isSlice() or (ty.zigTypeTag(mod) == .Optional and ty.optionalChild(&buf).isSlice())) {
+ if (ty.isSlice(mod) or (ty.zigTypeTag(mod) == .Optional and ty.optionalChild(&buf).isSlice(mod))) {
it.llvm_index += 1;
return .slice;
} else if (isByRef(ty, mod)) {
src/codegen/spirv.zig
@@ -2980,12 +2980,12 @@ pub const DeclGen = struct {
// Pointer payload represents nullability: pointer or slice.
var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const ptr_ty = if (payload_ty.isSlice())
+ const ptr_ty = if (payload_ty.isSlice(mod))
payload_ty.slicePtrFieldType(&ptr_buf)
else
payload_ty;
- const ptr_id = if (payload_ty.isSlice())
+ const ptr_id = if (payload_ty.isSlice(mod))
try self.extractField(Type.bool, operand_id, 0)
else
operand_id;
src/link/Dwarf.zig
@@ -258,7 +258,7 @@ pub const DeclState = struct {
}
},
.Pointer => {
- if (ty.isSlice()) {
+ if (ty.isSlice(mod)) {
// Slices are structs: struct { .ptr = *, .len = N }
const ptr_bits = target.ptrBitWidth();
const ptr_bytes = @intCast(u8, @divExact(ptr_bits, 8));
src/codegen.zig
@@ -317,11 +317,11 @@ pub fn generateSymbol(
switch (target.ptrBitWidth()) {
32 => {
mem.writeInt(u32, try code.addManyAsArray(4), 0, endian);
- if (typed_value.ty.isSlice()) try code.appendNTimes(0xaa, 4);
+ if (typed_value.ty.isSlice(mod)) try code.appendNTimes(0xaa, 4);
},
64 => {
mem.writeInt(u64, try code.addManyAsArray(8), 0, endian);
- if (typed_value.ty.isSlice()) try code.appendNTimes(0xaa, 8);
+ if (typed_value.ty.isSlice(mod)) try code.appendNTimes(0xaa, 8);
},
else => unreachable,
}
@@ -845,7 +845,7 @@ fn lowerParentPtr(
debug_output,
reloc_info.offset(@intCast(u32, switch (field_ptr.container_ty.zigTypeTag(mod)) {
.Pointer => offset: {
- assert(field_ptr.container_ty.isSlice());
+ assert(field_ptr.container_ty.isSlice(mod));
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
break :offset switch (field_ptr.field_index) {
0 => 0,
@@ -946,7 +946,7 @@ fn lowerDeclRef(
) CodeGenError!Result {
const target = bin_file.options.target;
const mod = bin_file.options.module.?;
- if (typed_value.ty.isSlice()) {
+ if (typed_value.ty.isSlice(mod)) {
// generate ptr
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf);
@@ -1174,7 +1174,7 @@ pub fn genTypedValue(
const target = bin_file.options.target;
const ptr_bits = target.ptrBitWidth();
- if (!typed_value.ty.isSlice()) {
+ if (!typed_value.ty.isSlice(mod)) {
if (typed_value.val.castTag(.variable)) |payload| {
return genDeclRef(bin_file, src_loc, typed_value, payload.data.owner_decl);
}
src/InternPool.zig
@@ -629,7 +629,7 @@ pub const Tag = enum(u8) {
/// A vector type.
/// data is payload to Vector.
type_vector,
- /// A pointer type along with all its bells and whistles.
+ /// A fully explicitly specified pointer type.
/// data is payload to Pointer.
type_pointer,
/// An optional type.
@@ -682,13 +682,13 @@ pub const Tag = enum(u8) {
/// An enum tag identified by a negative integer value.
/// data is a limbs index to Int.
enum_tag_negative,
- /// A float value that can be represented by f32.
+ /// An f32 value.
/// data is float value bitcasted to u32.
float_f32,
- /// A float value that can be represented by f64.
+ /// An f64 value.
/// data is payload index to Float64.
float_f64,
- /// A float value that can be represented by f128.
+ /// An f128 value.
/// data is payload index to Float128.
float_f128,
/// An extern function.
@@ -871,7 +871,47 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
.simple_type => .{ .simple_type = @intToEnum(SimpleType, data) },
.simple_value => .{ .simple_value = @intToEnum(SimpleValue, data) },
- else => @panic("TODO"),
+ .type_vector => {
+ const vector_info = ip.extraData(Vector, data);
+ return .{ .vector_type = .{
+ .len = vector_info.len,
+ .child = vector_info.child,
+ } };
+ },
+
+ .type_pointer => {
+ const ptr_info = ip.extraData(Pointer, data);
+ return .{ .ptr_type = .{
+ .elem_type = ptr_info.child,
+ .sentinel = ptr_info.sentinel,
+ .alignment = ptr_info.flags.alignment,
+ .size = ptr_info.flags.size,
+ .is_const = ptr_info.flags.is_const,
+ .is_volatile = ptr_info.flags.is_volatile,
+ .is_allowzero = ptr_info.flags.is_allowzero,
+ .address_space = ptr_info.flags.address_space,
+ } };
+ },
+
+ .type_optional => .{ .optional_type = .{ .payload_type = @intToEnum(Index, data) } },
+
+ .type_error_union => @panic("TODO"),
+ .type_enum_simple => @panic("TODO"),
+ .simple_internal => @panic("TODO"),
+ .int_small_u32 => @panic("TODO"),
+ .int_small_i32 => @panic("TODO"),
+ .int_small_usize => @panic("TODO"),
+ .int_small_comptime_unsigned => @panic("TODO"),
+ .int_small_comptime_signed => @panic("TODO"),
+ .int_positive => @panic("TODO"),
+ .int_negative => @panic("TODO"),
+ .enum_tag_positive => @panic("TODO"),
+ .enum_tag_negative => @panic("TODO"),
+ .float_f32 => @panic("TODO"),
+ .float_f64 => @panic("TODO"),
+ .float_f128 => @panic("TODO"),
+ .extern_func => @panic("TODO"),
+ .func => @panic("TODO"),
};
}
src/Sema.zig
@@ -2030,7 +2030,7 @@ fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty
ty.fmt(mod),
});
errdefer msg.destroy(sema.gpa);
- if (ty.isSlice()) {
+ if (ty.isSlice(mod)) {
try sema.errNote(block, src, msg, "inferred array length is specified with an underscore: '[_]{}'", .{ty.elemType2(mod).fmt(mod)});
}
break :msg msg;
@@ -10359,7 +10359,7 @@ fn zirSwitchCond(
.ErrorSet,
.Enum,
=> {
- if (operand_ty.isSlice()) {
+ if (operand_ty.isSlice(mod)) {
return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(sema.mod)});
}
if ((try sema.typeHasOnePossibleValue(operand_ty))) |opv| {
@@ -12017,7 +12017,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
const ty = try sema.resolveTypeFields(unresolved_ty);
const has_field = hf: {
- if (ty.isSlice()) {
+ if (ty.isSlice(mod)) {
if (mem.eql(u8, field_name, "ptr")) break :hf true;
if (mem.eql(u8, field_name, "len")) break :hf true;
break :hf false;
@@ -20020,8 +20020,8 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
return sema.failWithOwnedErrorMsg(msg);
}
- const dest_is_slice = dest_ty.isSlice();
- const operand_is_slice = operand_ty.isSlice();
+ const dest_is_slice = dest_ty.isSlice(mod);
+ const operand_is_slice = operand_ty.isSlice(mod);
if (dest_is_slice and !operand_is_slice) {
return sema.fail(block, dest_ty_src, "illegal pointer cast to slice", .{});
}
@@ -20274,14 +20274,14 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
Type.usize,
Value.initPayload(&val_payload.base),
);
- const actual_ptr = if (ptr_ty.isSlice())
+ const actual_ptr = if (ptr_ty.isSlice(mod))
try sema.analyzeSlicePtr(block, ptr_src, ptr, ptr_ty)
else
ptr;
const ptr_int = try block.addUnOp(.ptrtoint, actual_ptr);
const remainder = try block.addBinOp(.bit_and, ptr_int, align_minus_1);
const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize);
- const ok = if (ptr_ty.isSlice()) ok: {
+ const ok = if (ptr_ty.isSlice(mod)) ok: {
const len = try sema.analyzeSliceLen(block, ptr_src, ptr);
const len_zero = try block.addBinOp(.cmp_eq, len, .zero_usize);
break :ok try block.addBinOp(.bit_or, len_zero, is_aligned);
@@ -22336,7 +22336,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
// Change the src from slice to a many pointer, to avoid multiple ptr
// slice extractions in AIR instructions.
const new_src_ptr_ty = sema.typeOf(new_src_ptr);
- if (new_src_ptr_ty.isSlice()) {
+ if (new_src_ptr_ty.isSlice(mod)) {
new_src_ptr = try sema.analyzeSlicePtr(block, src_src, new_src_ptr, new_src_ptr_ty);
}
} else if (dest_len == .none and len_val == null) {
@@ -22344,7 +22344,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
const dest_ptr_ptr = try sema.analyzeRef(block, dest_src, new_dest_ptr);
new_dest_ptr = try sema.analyzeSlice(block, dest_src, dest_ptr_ptr, .zero, src_len, .none, .unneeded, dest_src, dest_src, dest_src, false);
const new_src_ptr_ty = sema.typeOf(new_src_ptr);
- if (new_src_ptr_ty.isSlice()) {
+ if (new_src_ptr_ty.isSlice(mod)) {
new_src_ptr = try sema.analyzeSlicePtr(block, src_src, new_src_ptr, new_src_ptr_ty);
}
}
@@ -22363,7 +22363,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
// Extract raw pointer from dest slice. The AIR instructions could support them, but
// it would cause redundant machine code instructions.
const new_dest_ptr_ty = sema.typeOf(new_dest_ptr);
- const raw_dest_ptr = if (new_dest_ptr_ty.isSlice())
+ const raw_dest_ptr = if (new_dest_ptr_ty.isSlice(mod))
try sema.analyzeSlicePtr(block, dest_src, new_dest_ptr, new_dest_ptr_ty)
else
new_dest_ptr;
@@ -23383,7 +23383,7 @@ fn validateExternType(
.Float,
.AnyFrame,
=> return true,
- .Pointer => return !(ty.isSlice() or try sema.typeRequiresComptime(ty)),
+ .Pointer => return !(ty.isSlice(mod) or try sema.typeRequiresComptime(ty)),
.Int => switch (ty.intInfo(mod).bits) {
8, 16, 32, 64, 128 => return true,
else => return false,
@@ -23448,7 +23448,7 @@ fn explainWhyTypeIsNotExtern(
=> return,
.Pointer => {
- if (ty.isSlice()) {
+ if (ty.isSlice(mod)) {
try mod.errNoteNonLazy(src_loc, msg, "slices have no guaranteed in-memory representation", .{});
} else {
const pointee_ty = ty.childType();
@@ -23523,7 +23523,7 @@ fn validatePackedType(ty: Type, mod: *const Module) bool {
.Vector,
.Enum,
=> return true,
- .Pointer => return !ty.isSlice(),
+ .Pointer => return !ty.isSlice(mod),
.Struct, .Union => return ty.containerLayout() == .Packed,
}
}
@@ -23803,7 +23803,7 @@ fn panicSentinelMismatch(
const expected_sentinel = try sema.addConstant(sentinel_ty, expected_sentinel_val);
const ptr_ty = sema.typeOf(ptr);
- const actual_sentinel = if (ptr_ty.isSlice())
+ const actual_sentinel = if (ptr_ty.isSlice(mod))
try parent_block.addBinOp(.slice_elem_val, ptr, sentinel_index)
else blk: {
const elem_ptr_ty = try sema.elemPtrType(ptr_ty, null);
@@ -24064,7 +24064,7 @@ fn fieldVal(
const msg = msg: {
const msg = try sema.errMsg(block, src, "type '{}' has no members", .{child_type.fmt(sema.mod)});
errdefer msg.destroy(sema.gpa);
- if (child_type.isSlice()) try sema.errNote(block, src, msg, "slice values have 'len' and 'ptr' members", .{});
+ if (child_type.isSlice(mod)) try sema.errNote(block, src, msg, "slice values have 'len' and 'ptr' members", .{});
if (child_type.zigTypeTag(mod) == .Array) try sema.errNote(block, src, msg, "array values have 'len' member", .{});
break :msg msg;
};
@@ -24140,7 +24140,7 @@ fn fieldPtr(
);
}
},
- .Pointer => if (inner_ty.isSlice()) {
+ .Pointer => if (inner_ty.isSlice(mod)) {
const inner_ptr = if (is_pointer_to)
try sema.analyzeLoad(block, src, object_ptr, object_ptr_src)
else
@@ -25743,8 +25743,8 @@ fn coerceExtra(
} };
break :pointer;
}
- if (dest_ty.isSlice()) break :to_anyopaque;
- if (inst_ty.isSlice()) {
+ if (dest_ty.isSlice(mod)) break :to_anyopaque;
+ if (inst_ty.isSlice(mod)) {
in_memory_result = .{ .slice_to_anyopaque = .{
.actual = inst_ty,
.wanted = dest_ty,
@@ -25885,7 +25885,7 @@ fn coerceExtra(
return sema.coerceTupleToSlicePtrs(block, dest_ty, dest_ty_src, inst, inst_src);
},
.Many => p: {
- if (!inst_ty.isSlice()) break :p;
+ if (!inst_ty.isSlice(mod)) break :p;
if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :p;
const inst_info = inst_ty.ptrInfo().data;
@@ -26651,7 +26651,7 @@ fn coerceInMemoryAllowed(
}
// Slices
- if (dest_ty.isSlice() and src_ty.isSlice()) {
+ if (dest_ty.isSlice(mod) and src_ty.isSlice(mod)) {
return try sema.coerceInMemoryAllowedPtrs(block, dest_ty, src_ty, dest_ty, src_ty, dest_is_mut, target, dest_src, src_src);
}
@@ -27744,7 +27744,7 @@ fn beginComptimePtrMutation(
);
},
.Pointer => {
- assert(parent.ty.isSlice());
+ assert(parent.ty.isSlice(mod));
val_ptr.* = try Value.Tag.slice.create(arena, .{
.ptr = Value.undef,
.len = Value.undef,
@@ -28187,7 +28187,7 @@ fn beginComptimePtrLoad(
break :blk deref;
}
- if (field_ptr.container_ty.isSlice()) {
+ if (field_ptr.container_ty.isSlice(mod)) {
const slice_val = tv.val.castTag(.slice).?.data;
deref.pointee = switch (field_index) {
Value.Payload.Slice.ptr_index => TypedValue{
@@ -28442,13 +28442,13 @@ fn coerceCompatiblePtrs(
if (block.wantSafety() and inst_allows_zero and !dest_ty.ptrAllowsZero(mod) and
(try sema.typeHasRuntimeBits(dest_ty.elemType2(mod)) or dest_ty.elemType2(mod).zigTypeTag(mod) == .Fn))
{
- const actual_ptr = if (inst_ty.isSlice())
+ const actual_ptr = if (inst_ty.isSlice(mod))
try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty)
else
inst;
const ptr_int = try block.addUnOp(.ptrtoint, actual_ptr);
const is_non_zero = try block.addBinOp(.cmp_neq, ptr_int, .zero_usize);
- const ok = if (inst_ty.isSlice()) ok: {
+ const ok = if (inst_ty.isSlice(mod)) ok: {
const len = try sema.analyzeSliceLen(block, inst_src, inst);
const len_zero = try block.addBinOp(.cmp_eq, len, .zero_usize);
break :ok try block.addBinOp(.bit_or, len_zero, is_non_zero);
@@ -29548,7 +29548,7 @@ fn analyzeSlice(
else => return sema.fail(block, src, "slice of non-array type '{}'", .{ptr_ptr_child_ty.fmt(mod)}),
}
- const ptr = if (slice_ty.isSlice())
+ const ptr = if (slice_ty.isSlice(mod))
try sema.analyzeSlicePtr(block, ptr_src, ptr_or_slice, slice_ty)
else
ptr_or_slice;
@@ -29605,7 +29605,7 @@ fn analyzeSlice(
}
break :e try sema.addConstant(Type.usize, len_val);
- } else if (slice_ty.isSlice()) {
+ } else if (slice_ty.isSlice(mod)) {
if (!end_is_len) {
const end = if (by_length) end: {
const len = try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);
@@ -29778,7 +29778,7 @@ fn analyzeSlice(
try sema.addSafetyCheck(block, is_non_null, .unwrap_null);
}
- if (slice_ty.isSlice()) {
+ if (slice_ty.isSlice(mod)) {
const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);
const actual_len = if (slice_ty.sentinel() == null)
slice_len_inst
@@ -29840,7 +29840,7 @@ fn analyzeSlice(
// requirement: end <= len
const opt_len_inst = if (array_ty.zigTypeTag(mod) == .Array)
try sema.addIntUnsigned(Type.usize, array_ty.arrayLenIncludingSentinel())
- else if (slice_ty.isSlice()) blk: {
+ else if (slice_ty.isSlice(mod)) blk: {
if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {
// we don't need to add one for sentinels because the
// underlying value data includes the sentinel
src/type.zig
@@ -229,7 +229,7 @@ pub const Type = struct {
.Frame,
=> false,
- .Pointer => !ty.isSlice() and (is_equality_cmp or ty.isCPtr()),
+ .Pointer => !ty.isSlice(mod) and (is_equality_cmp or ty.isCPtr()),
.Optional => {
if (!is_equality_cmp) return false;
var buf: Payload.ElemType = undefined;
@@ -369,209 +369,212 @@ pub const Type = struct {
}
pub fn ptrInfo(self: Type) Payload.Pointer {
- switch (self.tag()) {
- .single_const_pointer_to_comptime_int => return .{ .data = .{
- .pointee_type = Type.comptime_int,
- .sentinel = null,
- .@"align" = 0,
- .@"addrspace" = .generic,
- .bit_offset = 0,
- .host_size = 0,
- .@"allowzero" = false,
- .mutable = false,
- .@"volatile" = false,
- .size = .One,
- } },
- .const_slice_u8 => return .{ .data = .{
- .pointee_type = Type.u8,
- .sentinel = null,
- .@"align" = 0,
- .@"addrspace" = .generic,
- .bit_offset = 0,
- .host_size = 0,
- .@"allowzero" = false,
- .mutable = false,
- .@"volatile" = false,
- .size = .Slice,
- } },
- .const_slice_u8_sentinel_0 => return .{ .data = .{
- .pointee_type = Type.u8,
- .sentinel = Value.zero,
- .@"align" = 0,
- .@"addrspace" = .generic,
- .bit_offset = 0,
- .host_size = 0,
- .@"allowzero" = false,
- .mutable = false,
- .@"volatile" = false,
- .size = .Slice,
- } },
- .single_const_pointer => return .{ .data = .{
- .pointee_type = self.castPointer().?.data,
- .sentinel = null,
- .@"align" = 0,
- .@"addrspace" = .generic,
- .bit_offset = 0,
- .host_size = 0,
- .@"allowzero" = false,
- .mutable = false,
- .@"volatile" = false,
- .size = .One,
- } },
- .single_mut_pointer => return .{ .data = .{
- .pointee_type = self.castPointer().?.data,
- .sentinel = null,
- .@"align" = 0,
- .@"addrspace" = .generic,
- .bit_offset = 0,
- .host_size = 0,
- .@"allowzero" = false,
- .mutable = true,
- .@"volatile" = false,
- .size = .One,
- } },
- .many_const_pointer => return .{ .data = .{
- .pointee_type = self.castPointer().?.data,
- .sentinel = null,
- .@"align" = 0,
- .@"addrspace" = .generic,
- .bit_offset = 0,
- .host_size = 0,
- .@"allowzero" = false,
- .mutable = false,
- .@"volatile" = false,
- .size = .Many,
- } },
- .manyptr_const_u8 => return .{ .data = .{
- .pointee_type = Type.u8,
- .sentinel = null,
- .@"align" = 0,
- .@"addrspace" = .generic,
- .bit_offset = 0,
- .host_size = 0,
- .@"allowzero" = false,
- .mutable = false,
- .@"volatile" = false,
- .size = .Many,
- } },
- .manyptr_const_u8_sentinel_0 => return .{ .data = .{
- .pointee_type = Type.u8,
- .sentinel = Value.zero,
- .@"align" = 0,
- .@"addrspace" = .generic,
- .bit_offset = 0,
- .host_size = 0,
- .@"allowzero" = false,
- .mutable = false,
- .@"volatile" = false,
- .size = .Many,
- } },
- .many_mut_pointer => return .{ .data = .{
- .pointee_type = self.castPointer().?.data,
- .sentinel = null,
- .@"align" = 0,
- .@"addrspace" = .generic,
- .bit_offset = 0,
- .host_size = 0,
- .@"allowzero" = false,
- .mutable = true,
- .@"volatile" = false,
- .size = .Many,
- } },
- .manyptr_u8 => return .{ .data = .{
- .pointee_type = Type.u8,
- .sentinel = null,
- .@"align" = 0,
- .@"addrspace" = .generic,
- .bit_offset = 0,
- .host_size = 0,
- .@"allowzero" = false,
- .mutable = true,
- .@"volatile" = false,
- .size = .Many,
- } },
- .c_const_pointer => return .{ .data = .{
- .pointee_type = self.castPointer().?.data,
- .sentinel = null,
- .@"align" = 0,
- .@"addrspace" = .generic,
- .bit_offset = 0,
- .host_size = 0,
- .@"allowzero" = true,
- .mutable = false,
- .@"volatile" = false,
- .size = .C,
- } },
- .c_mut_pointer => return .{ .data = .{
- .pointee_type = self.castPointer().?.data,
- .sentinel = null,
- .@"align" = 0,
- .@"addrspace" = .generic,
- .bit_offset = 0,
- .host_size = 0,
- .@"allowzero" = true,
- .mutable = true,
- .@"volatile" = false,
- .size = .C,
- } },
- .const_slice => return .{ .data = .{
- .pointee_type = self.castPointer().?.data,
- .sentinel = null,
- .@"align" = 0,
- .@"addrspace" = .generic,
- .bit_offset = 0,
- .host_size = 0,
- .@"allowzero" = false,
- .mutable = false,
- .@"volatile" = false,
- .size = .Slice,
- } },
- .mut_slice => return .{ .data = .{
- .pointee_type = self.castPointer().?.data,
- .sentinel = null,
- .@"align" = 0,
- .@"addrspace" = .generic,
- .bit_offset = 0,
- .host_size = 0,
- .@"allowzero" = false,
- .mutable = true,
- .@"volatile" = false,
- .size = .Slice,
- } },
-
- .pointer => return self.castTag(.pointer).?.*,
-
- .optional_single_mut_pointer => return .{ .data = .{
- .pointee_type = self.castPointer().?.data,
- .sentinel = null,
- .@"align" = 0,
- .@"addrspace" = .generic,
- .bit_offset = 0,
- .host_size = 0,
- .@"allowzero" = false,
- .mutable = true,
- .@"volatile" = false,
- .size = .One,
- } },
- .optional_single_const_pointer => return .{ .data = .{
- .pointee_type = self.castPointer().?.data,
- .sentinel = null,
- .@"align" = 0,
- .@"addrspace" = .generic,
- .bit_offset = 0,
- .host_size = 0,
- .@"allowzero" = false,
- .mutable = false,
- .@"volatile" = false,
- .size = .One,
- } },
- .optional => {
- var buf: Payload.ElemType = undefined;
- const child_type = self.optionalChild(&buf);
- return child_type.ptrInfo();
- },
+ switch (self.ip_index) {
+ .none => switch (self.tag()) {
+ .single_const_pointer_to_comptime_int => return .{ .data = .{
+ .pointee_type = Type.comptime_int,
+ .sentinel = null,
+ .@"align" = 0,
+ .@"addrspace" = .generic,
+ .bit_offset = 0,
+ .host_size = 0,
+ .@"allowzero" = false,
+ .mutable = false,
+ .@"volatile" = false,
+ .size = .One,
+ } },
+ .const_slice_u8 => return .{ .data = .{
+ .pointee_type = Type.u8,
+ .sentinel = null,
+ .@"align" = 0,
+ .@"addrspace" = .generic,
+ .bit_offset = 0,
+ .host_size = 0,
+ .@"allowzero" = false,
+ .mutable = false,
+ .@"volatile" = false,
+ .size = .Slice,
+ } },
+ .const_slice_u8_sentinel_0 => return .{ .data = .{
+ .pointee_type = Type.u8,
+ .sentinel = Value.zero,
+ .@"align" = 0,
+ .@"addrspace" = .generic,
+ .bit_offset = 0,
+ .host_size = 0,
+ .@"allowzero" = false,
+ .mutable = false,
+ .@"volatile" = false,
+ .size = .Slice,
+ } },
+ .single_const_pointer => return .{ .data = .{
+ .pointee_type = self.castPointer().?.data,
+ .sentinel = null,
+ .@"align" = 0,
+ .@"addrspace" = .generic,
+ .bit_offset = 0,
+ .host_size = 0,
+ .@"allowzero" = false,
+ .mutable = false,
+ .@"volatile" = false,
+ .size = .One,
+ } },
+ .single_mut_pointer => return .{ .data = .{
+ .pointee_type = self.castPointer().?.data,
+ .sentinel = null,
+ .@"align" = 0,
+ .@"addrspace" = .generic,
+ .bit_offset = 0,
+ .host_size = 0,
+ .@"allowzero" = false,
+ .mutable = true,
+ .@"volatile" = false,
+ .size = .One,
+ } },
+ .many_const_pointer => return .{ .data = .{
+ .pointee_type = self.castPointer().?.data,
+ .sentinel = null,
+ .@"align" = 0,
+ .@"addrspace" = .generic,
+ .bit_offset = 0,
+ .host_size = 0,
+ .@"allowzero" = false,
+ .mutable = false,
+ .@"volatile" = false,
+ .size = .Many,
+ } },
+ .manyptr_const_u8 => return .{ .data = .{
+ .pointee_type = Type.u8,
+ .sentinel = null,
+ .@"align" = 0,
+ .@"addrspace" = .generic,
+ .bit_offset = 0,
+ .host_size = 0,
+ .@"allowzero" = false,
+ .mutable = false,
+ .@"volatile" = false,
+ .size = .Many,
+ } },
+ .manyptr_const_u8_sentinel_0 => return .{ .data = .{
+ .pointee_type = Type.u8,
+ .sentinel = Value.zero,
+ .@"align" = 0,
+ .@"addrspace" = .generic,
+ .bit_offset = 0,
+ .host_size = 0,
+ .@"allowzero" = false,
+ .mutable = false,
+ .@"volatile" = false,
+ .size = .Many,
+ } },
+ .many_mut_pointer => return .{ .data = .{
+ .pointee_type = self.castPointer().?.data,
+ .sentinel = null,
+ .@"align" = 0,
+ .@"addrspace" = .generic,
+ .bit_offset = 0,
+ .host_size = 0,
+ .@"allowzero" = false,
+ .mutable = true,
+ .@"volatile" = false,
+ .size = .Many,
+ } },
+ .manyptr_u8 => return .{ .data = .{
+ .pointee_type = Type.u8,
+ .sentinel = null,
+ .@"align" = 0,
+ .@"addrspace" = .generic,
+ .bit_offset = 0,
+ .host_size = 0,
+ .@"allowzero" = false,
+ .mutable = true,
+ .@"volatile" = false,
+ .size = .Many,
+ } },
+ .c_const_pointer => return .{ .data = .{
+ .pointee_type = self.castPointer().?.data,
+ .sentinel = null,
+ .@"align" = 0,
+ .@"addrspace" = .generic,
+ .bit_offset = 0,
+ .host_size = 0,
+ .@"allowzero" = true,
+ .mutable = false,
+ .@"volatile" = false,
+ .size = .C,
+ } },
+ .c_mut_pointer => return .{ .data = .{
+ .pointee_type = self.castPointer().?.data,
+ .sentinel = null,
+ .@"align" = 0,
+ .@"addrspace" = .generic,
+ .bit_offset = 0,
+ .host_size = 0,
+ .@"allowzero" = true,
+ .mutable = true,
+ .@"volatile" = false,
+ .size = .C,
+ } },
+ .const_slice => return .{ .data = .{
+ .pointee_type = self.castPointer().?.data,
+ .sentinel = null,
+ .@"align" = 0,
+ .@"addrspace" = .generic,
+ .bit_offset = 0,
+ .host_size = 0,
+ .@"allowzero" = false,
+ .mutable = false,
+ .@"volatile" = false,
+ .size = .Slice,
+ } },
+ .mut_slice => return .{ .data = .{
+ .pointee_type = self.castPointer().?.data,
+ .sentinel = null,
+ .@"align" = 0,
+ .@"addrspace" = .generic,
+ .bit_offset = 0,
+ .host_size = 0,
+ .@"allowzero" = false,
+ .mutable = true,
+ .@"volatile" = false,
+ .size = .Slice,
+ } },
+
+ .pointer => return self.castTag(.pointer).?.*,
+
+ .optional_single_mut_pointer => return .{ .data = .{
+ .pointee_type = self.castPointer().?.data,
+ .sentinel = null,
+ .@"align" = 0,
+ .@"addrspace" = .generic,
+ .bit_offset = 0,
+ .host_size = 0,
+ .@"allowzero" = false,
+ .mutable = true,
+ .@"volatile" = false,
+ .size = .One,
+ } },
+ .optional_single_const_pointer => return .{ .data = .{
+ .pointee_type = self.castPointer().?.data,
+ .sentinel = null,
+ .@"align" = 0,
+ .@"addrspace" = .generic,
+ .bit_offset = 0,
+ .host_size = 0,
+ .@"allowzero" = false,
+ .mutable = false,
+ .@"volatile" = false,
+ .size = .One,
+ } },
+ .optional => {
+ var buf: Payload.ElemType = undefined;
+ const child_type = self.optionalChild(&buf);
+ return child_type.ptrInfo();
+ },
- else => unreachable,
+ else => unreachable,
+ },
+ else => @panic("TODO"),
}
}
@@ -3712,17 +3715,23 @@ pub const Type = struct {
};
}
- pub fn isSlice(self: Type) bool {
- return switch (self.tag()) {
- .const_slice,
- .mut_slice,
- .const_slice_u8,
- .const_slice_u8_sentinel_0,
- => true,
+ pub fn isSlice(ty: Type, mod: *const Module) bool {
+ return switch (ty.ip_index) {
+ .none => switch (ty.tag()) {
+ .const_slice,
+ .mut_slice,
+ .const_slice_u8,
+ .const_slice_u8_sentinel_0,
+ => true,
- .pointer => self.castTag(.pointer).?.data.size == .Slice,
+ .pointer => ty.castTag(.pointer).?.data.size == .Slice,
- else => false,
+ else => false,
+ },
+ else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
+ .ptr_type => |ptr_type| ptr_type.size == .Slice,
+ else => false,
+ },
};
}
src/TypedValue.zig
@@ -259,7 +259,7 @@ pub fn print(
} else if (field_ptr.container_ty.zigTypeTag(mod) == .Union) {
const field_name = field_ptr.container_ty.unionFields().keys()[field_ptr.field_index];
return writer.print(".{s}", .{field_name});
- } else if (field_ptr.container_ty.isSlice()) {
+ } else if (field_ptr.container_ty.isSlice(mod)) {
switch (field_ptr.field_index) {
Value.Payload.Slice.ptr_index => return writer.writeAll(".ptr"),
Value.Payload.Slice.len_index => return writer.writeAll(".len"),
src/value.zig
@@ -1144,7 +1144,7 @@ pub const Value = struct {
},
},
.Pointer => {
- if (ty.isSlice()) return error.IllDefinedMemoryLayout;
+ if (ty.isSlice(mod)) return error.IllDefinedMemoryLayout;
if (val.isDeclRef()) return error.ReinterpretDeclRef;
return val.writeToMemory(Type.usize, mod, buffer);
},
@@ -1261,7 +1261,7 @@ pub const Value = struct {
},
},
.Pointer => {
- assert(!ty.isSlice()); // No well defined layout.
+ assert(!ty.isSlice(mod)); // No well defined layout.
if (val.isDeclRef()) return error.ReinterpretDeclRef;
return val.writeToPackedMemory(Type.usize, mod, buffer, bit_offset);
},
@@ -1381,7 +1381,7 @@ pub const Value = struct {
return Value.initPayload(&payload.base);
},
.Pointer => {
- assert(!ty.isSlice()); // No well defined layout.
+ assert(!ty.isSlice(mod)); // No well defined layout.
return readFromMemory(Type.usize, mod, buffer, arena);
},
.Optional => {
@@ -1478,7 +1478,7 @@ pub const Value = struct {
},
},
.Pointer => {
- assert(!ty.isSlice()); // No well defined layout.
+ assert(!ty.isSlice(mod)); // No well defined layout.
return readFromPackedMemory(Type.usize, mod, buffer, bit_offset, arena);
},
.Optional => {