mirror of
https://github.com/ziglang/zig.git
synced 2025-12-15 10:43:08 +00:00
InternPool: implement isSinglePointer
This commit is contained in:
parent
e77dede87e
commit
aa1bb5517d
31
src/Sema.zig
31
src/Sema.zig
@ -2086,7 +2086,7 @@ fn failWithUseOfAsync(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError
|
||||
|
||||
fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, object_ty: Type, field_name: []const u8) CompileError {
|
||||
const mod = sema.mod;
|
||||
const inner_ty = if (object_ty.isSinglePointer()) object_ty.childType() else object_ty;
|
||||
const inner_ty = if (object_ty.isSinglePointer(mod)) object_ty.childType() else object_ty;
|
||||
|
||||
if (inner_ty.zigTypeTag(mod) == .Optional) opt: {
|
||||
var buf: Type.Payload.ElemType = undefined;
|
||||
@ -3412,8 +3412,9 @@ fn indexablePtrLen(
|
||||
src: LazySrcLoc,
|
||||
object: Air.Inst.Ref,
|
||||
) CompileError!Air.Inst.Ref {
|
||||
const mod = sema.mod;
|
||||
const object_ty = sema.typeOf(object);
|
||||
const is_pointer_to = object_ty.isSinglePointer();
|
||||
const is_pointer_to = object_ty.isSinglePointer(mod);
|
||||
const indexable_ty = if (is_pointer_to) object_ty.childType() else object_ty;
|
||||
try checkIndexable(sema, block, src, indexable_ty);
|
||||
return sema.fieldVal(block, src, object, "len", src);
|
||||
@ -12764,12 +12765,12 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
.Pointer => try sema.resolveDefinedValue(block, rhs_src, rhs),
|
||||
else => unreachable,
|
||||
}) |rhs_val| {
|
||||
const lhs_sub_val = if (lhs_ty.isSinglePointer())
|
||||
const lhs_sub_val = if (lhs_ty.isSinglePointer(mod))
|
||||
(try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).?
|
||||
else
|
||||
lhs_val;
|
||||
|
||||
const rhs_sub_val = if (rhs_ty.isSinglePointer())
|
||||
const rhs_sub_val = if (rhs_ty.isSinglePointer(mod))
|
||||
(try sema.pointerDeref(block, rhs_src, rhs_val, rhs_ty)).?
|
||||
else
|
||||
rhs_val;
|
||||
@ -13022,7 +13023,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| {
|
||||
const final_len_including_sent = result_len + @boolToInt(lhs_info.sentinel != null);
|
||||
|
||||
const lhs_sub_val = if (lhs_ty.isSinglePointer())
|
||||
const lhs_sub_val = if (lhs_ty.isSinglePointer(mod))
|
||||
(try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).?
|
||||
else
|
||||
lhs_val;
|
||||
@ -17588,7 +17589,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
|
||||
const elem_ty = blk: {
|
||||
const air_inst = try sema.resolveInst(extra.data.elem_type);
|
||||
const ty = sema.analyzeAsType(block, elem_ty_src, air_inst) catch |err| {
|
||||
if (err == error.AnalysisFail and sema.err != null and sema.typeOf(air_inst).isSinglePointer()) {
|
||||
if (err == error.AnalysisFail and sema.err != null and sema.typeOf(air_inst).isSinglePointer(mod)) {
|
||||
try sema.errNote(block, elem_ty_src, sema.err.?, "use '.*' to dereference pointer", .{});
|
||||
}
|
||||
return err;
|
||||
@ -23902,7 +23903,7 @@ fn fieldVal(
|
||||
// Zig allows dereferencing a single pointer during field lookup. Note that
|
||||
// we don't actually need to generate the dereference some field lookups, like the
|
||||
// length of arrays and other comptime operations.
|
||||
const is_pointer_to = object_ty.isSinglePointer();
|
||||
const is_pointer_to = object_ty.isSinglePointer(mod);
|
||||
|
||||
const inner_ty = if (is_pointer_to)
|
||||
object_ty.childType()
|
||||
@ -24092,7 +24093,7 @@ fn fieldPtr(
|
||||
// Zig allows dereferencing a single pointer during field lookup. Note that
|
||||
// we don't actually need to generate the dereference some field lookups, like the
|
||||
// length of arrays and other comptime operations.
|
||||
const is_pointer_to = object_ty.isSinglePointer();
|
||||
const is_pointer_to = object_ty.isSinglePointer(mod);
|
||||
|
||||
const inner_ty = if (is_pointer_to)
|
||||
object_ty.childType()
|
||||
@ -25622,7 +25623,7 @@ fn coerceExtra(
|
||||
// *T to *[1]T
|
||||
single_item: {
|
||||
if (dest_info.size != .One) break :single_item;
|
||||
if (!inst_ty.isSinglePointer()) break :single_item;
|
||||
if (!inst_ty.isSinglePointer(mod)) break :single_item;
|
||||
if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
|
||||
const ptr_elem_ty = inst_ty.childType();
|
||||
const array_ty = dest_info.pointee_type;
|
||||
@ -25639,7 +25640,7 @@ fn coerceExtra(
|
||||
|
||||
// Coercions where the source is a single pointer to an array.
|
||||
src_array_ptr: {
|
||||
if (!inst_ty.isSinglePointer()) break :src_array_ptr;
|
||||
if (!inst_ty.isSinglePointer(mod)) break :src_array_ptr;
|
||||
if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
|
||||
const array_ty = inst_ty.childType();
|
||||
if (array_ty.zigTypeTag(mod) != .Array) break :src_array_ptr;
|
||||
@ -25794,7 +25795,7 @@ fn coerceExtra(
|
||||
.One => switch (dest_info.pointee_type.zigTypeTag(mod)) {
|
||||
.Union => {
|
||||
// pointer to anonymous struct to pointer to union
|
||||
if (inst_ty.isSinglePointer() and
|
||||
if (inst_ty.isSinglePointer(mod) and
|
||||
inst_ty.childType().isAnonStruct() and
|
||||
sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
|
||||
{
|
||||
@ -25803,7 +25804,7 @@ fn coerceExtra(
|
||||
},
|
||||
.Struct => {
|
||||
// pointer to anonymous struct to pointer to struct
|
||||
if (inst_ty.isSinglePointer() and
|
||||
if (inst_ty.isSinglePointer(mod) and
|
||||
inst_ty.childType().isAnonStruct() and
|
||||
sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
|
||||
{
|
||||
@ -25815,7 +25816,7 @@ fn coerceExtra(
|
||||
},
|
||||
.Array => {
|
||||
// pointer to tuple to pointer to array
|
||||
if (inst_ty.isSinglePointer() and
|
||||
if (inst_ty.isSinglePointer(mod) and
|
||||
inst_ty.childType().isTuple() and
|
||||
sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
|
||||
{
|
||||
@ -25834,7 +25835,7 @@ fn coerceExtra(
|
||||
);
|
||||
}
|
||||
|
||||
if (!inst_ty.isSinglePointer()) break :to_slice;
|
||||
if (!inst_ty.isSinglePointer(mod)) break :to_slice;
|
||||
const inst_child_ty = inst_ty.childType();
|
||||
if (!inst_child_ty.isTuple()) break :to_slice;
|
||||
|
||||
@ -30807,7 +30808,7 @@ fn resolvePeerTypes(
|
||||
.Vector => continue,
|
||||
else => {},
|
||||
},
|
||||
.Fn => if (chosen_ty.isSinglePointer() and chosen_ty.isConstPtr() and chosen_ty.childType().zigTypeTag(mod) == .Fn) {
|
||||
.Fn => if (chosen_ty.isSinglePointer(mod) and chosen_ty.isConstPtr() and chosen_ty.childType().zigTypeTag(mod) == .Fn) {
|
||||
if (.ok == try sema.coerceInMemoryAllowedFns(block, chosen_ty.childType(), candidate_ty, target, src, src)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -3873,7 +3873,7 @@ fn airCmpOp(
|
||||
try reap(f, inst, &.{ data.lhs, data.rhs });
|
||||
|
||||
const rhs_ty = f.typeOf(data.rhs);
|
||||
const need_cast = lhs_ty.isSinglePointer() or rhs_ty.isSinglePointer();
|
||||
const need_cast = lhs_ty.isSinglePointer(mod) or rhs_ty.isSinglePointer(mod);
|
||||
const writer = f.object.writer();
|
||||
const local = try f.allocLocal(inst, inst_ty);
|
||||
const v = try Vectorize.start(f, inst, writer, lhs_ty);
|
||||
|
||||
@ -5929,7 +5929,7 @@ pub const FuncGen = struct {
|
||||
const base_ptr = try self.resolveInst(bin_op.lhs);
|
||||
const rhs = try self.resolveInst(bin_op.rhs);
|
||||
// TODO: when we go fully opaque pointers in LLVM 16 we can remove this branch
|
||||
const ptr = if (ptr_ty.isSinglePointer()) ptr: {
|
||||
const ptr = if (ptr_ty.isSinglePointer(mod)) ptr: {
|
||||
// If this is a single-item pointer to an array, we need another index in the GEP.
|
||||
const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };
|
||||
break :ptr self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
|
||||
@ -5962,7 +5962,7 @@ pub const FuncGen = struct {
|
||||
if (elem_ptr.ptrInfo().data.vector_index != .none) return base_ptr;
|
||||
|
||||
const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty);
|
||||
if (ptr_ty.isSinglePointer()) {
|
||||
if (ptr_ty.isSinglePointer(mod)) {
|
||||
// If this is a single-item pointer to an array, we need another index in the GEP.
|
||||
const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };
|
||||
return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
|
||||
|
||||
33
src/type.zig
33
src/type.zig
@ -4039,19 +4039,25 @@ pub const Type = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn isSinglePointer(self: Type) bool {
|
||||
return switch (self.tag()) {
|
||||
.single_const_pointer,
|
||||
.single_mut_pointer,
|
||||
.single_const_pointer_to_comptime_int,
|
||||
.inferred_alloc_const,
|
||||
.inferred_alloc_mut,
|
||||
=> true,
|
||||
pub fn isSinglePointer(ty: Type, mod: *const Module) bool {
|
||||
switch (ty.ip_index) {
|
||||
.none => return switch (ty.tag()) {
|
||||
.single_const_pointer,
|
||||
.single_mut_pointer,
|
||||
.single_const_pointer_to_comptime_int,
|
||||
.inferred_alloc_const,
|
||||
.inferred_alloc_mut,
|
||||
=> true,
|
||||
|
||||
.pointer => self.castTag(.pointer).?.data.size == .One,
|
||||
.pointer => ty.castTag(.pointer).?.data.size == .One,
|
||||
|
||||
else => false,
|
||||
};
|
||||
else => false,
|
||||
},
|
||||
else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||
.ptr_type => |ptr_info| ptr_info.size == .One,
|
||||
else => false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Asserts `ty` is a pointer.
|
||||
@ -6142,6 +6148,11 @@ pub const Type = struct {
|
||||
}
|
||||
|
||||
pub fn declSrcLocOrNull(ty: Type, mod: *Module) ?Module.SrcLoc {
|
||||
if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||
.struct_type => @panic("TODO"),
|
||||
.union_type => @panic("TODO"),
|
||||
else => return null,
|
||||
};
|
||||
switch (ty.tag()) {
|
||||
.enum_full, .enum_nonexhaustive => {
|
||||
const enum_full = ty.cast(Payload.EnumFull).?.data;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user