authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-03 13:56:01-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:40:03-07:00
logaa1bb5517d57ae7540ce2c7a4315b2f242d1470c
tree66d47066f1b2441d967979483fc00703f5abe9de
parente77dede87e8cff2679485aecf0d3af146595db3a

InternPool: implement isSinglePointer


4 files changed, 41 insertions(+), 29 deletions(-)

src/Sema.zig+16-15
......@@ -2086,7 +2086,7 @@ fn failWithUseOfAsync(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError
20862086
20872087fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, object_ty: Type, field_name: []const u8) CompileError {
20882088 const mod = sema.mod;
2089 const inner_ty = if (object_ty.isSinglePointer()) object_ty.childType() else object_ty;
2089 const inner_ty = if (object_ty.isSinglePointer(mod)) object_ty.childType() else object_ty;
20902090
20912091 if (inner_ty.zigTypeTag(mod) == .Optional) opt: {
20922092 var buf: Type.Payload.ElemType = undefined;
......@@ -3412,8 +3412,9 @@ fn indexablePtrLen(
34123412 src: LazySrcLoc,
34133413 object: Air.Inst.Ref,
34143414) CompileError!Air.Inst.Ref {
3415 const mod = sema.mod;
34153416 const object_ty = sema.typeOf(object);
3416 const is_pointer_to = object_ty.isSinglePointer();
3417 const is_pointer_to = object_ty.isSinglePointer(mod);
34173418 const indexable_ty = if (is_pointer_to) object_ty.childType() else object_ty;
34183419 try checkIndexable(sema, block, src, indexable_ty);
34193420 return sema.fieldVal(block, src, object, "len", src);
......@@ -12764,12 +12765,12 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1276412765 .Pointer => try sema.resolveDefinedValue(block, rhs_src, rhs),
1276512766 else => unreachable,
1276612767 }) |rhs_val| {
12767 const lhs_sub_val = if (lhs_ty.isSinglePointer())
12768 const lhs_sub_val = if (lhs_ty.isSinglePointer(mod))
1276812769 (try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).?
1276912770 else
1277012771 lhs_val;
1277112772
12772 const rhs_sub_val = if (rhs_ty.isSinglePointer())
12773 const rhs_sub_val = if (rhs_ty.isSinglePointer(mod))
1277312774 (try sema.pointerDeref(block, rhs_src, rhs_val, rhs_ty)).?
1277412775 else
1277512776 rhs_val;
......@@ -13022,7 +13023,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1302213023 if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| {
1302313024 const final_len_including_sent = result_len + @boolToInt(lhs_info.sentinel != null);
1302413025
13025 const lhs_sub_val = if (lhs_ty.isSinglePointer())
13026 const lhs_sub_val = if (lhs_ty.isSinglePointer(mod))
1302613027 (try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).?
1302713028 else
1302813029 lhs_val;
......@@ -17588,7 +17589,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1758817589 const elem_ty = blk: {
1758917590 const air_inst = try sema.resolveInst(extra.data.elem_type);
1759017591 const ty = sema.analyzeAsType(block, elem_ty_src, air_inst) catch |err| {
17591 if (err == error.AnalysisFail and sema.err != null and sema.typeOf(air_inst).isSinglePointer()) {
17592 if (err == error.AnalysisFail and sema.err != null and sema.typeOf(air_inst).isSinglePointer(mod)) {
1759217593 try sema.errNote(block, elem_ty_src, sema.err.?, "use '.*' to dereference pointer", .{});
1759317594 }
1759417595 return err;
......@@ -23902,7 +23903,7 @@ fn fieldVal(
2390223903 // Zig allows dereferencing a single pointer during field lookup. Note that
2390323904 // we don't actually need to generate the dereference some field lookups, like the
2390423905 // length of arrays and other comptime operations.
23905 const is_pointer_to = object_ty.isSinglePointer();
23906 const is_pointer_to = object_ty.isSinglePointer(mod);
2390623907
2390723908 const inner_ty = if (is_pointer_to)
2390823909 object_ty.childType()
......@@ -24092,7 +24093,7 @@ fn fieldPtr(
2409224093 // Zig allows dereferencing a single pointer during field lookup. Note that
2409324094 // we don't actually need to generate the dereference some field lookups, like the
2409424095 // length of arrays and other comptime operations.
24095 const is_pointer_to = object_ty.isSinglePointer();
24096 const is_pointer_to = object_ty.isSinglePointer(mod);
2409624097
2409724098 const inner_ty = if (is_pointer_to)
2409824099 object_ty.childType()
......@@ -25622,7 +25623,7 @@ fn coerceExtra(
2562225623 // *T to *[1]T
2562325624 single_item: {
2562425625 if (dest_info.size != .One) break :single_item;
25625 if (!inst_ty.isSinglePointer()) break :single_item;
25626 if (!inst_ty.isSinglePointer(mod)) break :single_item;
2562625627 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
2562725628 const ptr_elem_ty = inst_ty.childType();
2562825629 const array_ty = dest_info.pointee_type;
......@@ -25639,7 +25640,7 @@ fn coerceExtra(
2563925640
2564025641 // Coercions where the source is a single pointer to an array.
2564125642 src_array_ptr: {
25642 if (!inst_ty.isSinglePointer()) break :src_array_ptr;
25643 if (!inst_ty.isSinglePointer(mod)) break :src_array_ptr;
2564325644 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
2564425645 const array_ty = inst_ty.childType();
2564525646 if (array_ty.zigTypeTag(mod) != .Array) break :src_array_ptr;
......@@ -25794,7 +25795,7 @@ fn coerceExtra(
2579425795 .One => switch (dest_info.pointee_type.zigTypeTag(mod)) {
2579525796 .Union => {
2579625797 // pointer to anonymous struct to pointer to union
25797 if (inst_ty.isSinglePointer() and
25798 if (inst_ty.isSinglePointer(mod) and
2579825799 inst_ty.childType().isAnonStruct() and
2579925800 sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
2580025801 {
......@@ -25803,7 +25804,7 @@ fn coerceExtra(
2580325804 },
2580425805 .Struct => {
2580525806 // pointer to anonymous struct to pointer to struct
25806 if (inst_ty.isSinglePointer() and
25807 if (inst_ty.isSinglePointer(mod) and
2580725808 inst_ty.childType().isAnonStruct() and
2580825809 sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
2580925810 {
......@@ -25815,7 +25816,7 @@ fn coerceExtra(
2581525816 },
2581625817 .Array => {
2581725818 // pointer to tuple to pointer to array
25818 if (inst_ty.isSinglePointer() and
25819 if (inst_ty.isSinglePointer(mod) and
2581925820 inst_ty.childType().isTuple() and
2582025821 sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
2582125822 {
......@@ -25834,7 +25835,7 @@ fn coerceExtra(
2583425835 );
2583525836 }
2583625837
25837 if (!inst_ty.isSinglePointer()) break :to_slice;
25838 if (!inst_ty.isSinglePointer(mod)) break :to_slice;
2583825839 const inst_child_ty = inst_ty.childType();
2583925840 if (!inst_child_ty.isTuple()) break :to_slice;
2584025841
......@@ -30807,7 +30808,7 @@ fn resolvePeerTypes(
3080730808 .Vector => continue,
3080830809 else => {},
3080930810 },
30810 .Fn => if (chosen_ty.isSinglePointer() and chosen_ty.isConstPtr() and chosen_ty.childType().zigTypeTag(mod) == .Fn) {
30811 .Fn => if (chosen_ty.isSinglePointer(mod) and chosen_ty.isConstPtr() and chosen_ty.childType().zigTypeTag(mod) == .Fn) {
3081130812 if (.ok == try sema.coerceInMemoryAllowedFns(block, chosen_ty.childType(), candidate_ty, target, src, src)) {
3081230813 continue;
3081330814 }
src/codegen/c.zig+1-1
......@@ -3873,7 +3873,7 @@ fn airCmpOp(
38733873 try reap(f, inst, &.{ data.lhs, data.rhs });
38743874
38753875 const rhs_ty = f.typeOf(data.rhs);
3876 const need_cast = lhs_ty.isSinglePointer() or rhs_ty.isSinglePointer();
3876 const need_cast = lhs_ty.isSinglePointer(mod) or rhs_ty.isSinglePointer(mod);
38773877 const writer = f.object.writer();
38783878 const local = try f.allocLocal(inst, inst_ty);
38793879 const v = try Vectorize.start(f, inst, writer, lhs_ty);
src/codegen/llvm.zig+2-2
......@@ -5929,7 +5929,7 @@ pub const FuncGen = struct {
59295929 const base_ptr = try self.resolveInst(bin_op.lhs);
59305930 const rhs = try self.resolveInst(bin_op.rhs);
59315931 // TODO: when we go fully opaque pointers in LLVM 16 we can remove this branch
5932 const ptr = if (ptr_ty.isSinglePointer()) ptr: {
5932 const ptr = if (ptr_ty.isSinglePointer(mod)) ptr: {
59335933 // If this is a single-item pointer to an array, we need another index in the GEP.
59345934 const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };
59355935 break :ptr self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
......@@ -5962,7 +5962,7 @@ pub const FuncGen = struct {
59625962 if (elem_ptr.ptrInfo().data.vector_index != .none) return base_ptr;
59635963
59645964 const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty);
5965 if (ptr_ty.isSinglePointer()) {
5965 if (ptr_ty.isSinglePointer(mod)) {
59665966 // If this is a single-item pointer to an array, we need another index in the GEP.
59675967 const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };
59685968 return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
src/type.zig+22-11
......@@ -4039,19 +4039,25 @@ pub const Type = struct {
40394039 }
40404040 }
40414041
4042 pub fn isSinglePointer(self: Type) bool {
4043 return switch (self.tag()) {
4044 .single_const_pointer,
4045 .single_mut_pointer,
4046 .single_const_pointer_to_comptime_int,
4047 .inferred_alloc_const,
4048 .inferred_alloc_mut,
4049 => true,
4042 pub fn isSinglePointer(ty: Type, mod: *const Module) bool {
4043 switch (ty.ip_index) {
4044 .none => return switch (ty.tag()) {
4045 .single_const_pointer,
4046 .single_mut_pointer,
4047 .single_const_pointer_to_comptime_int,
4048 .inferred_alloc_const,
4049 .inferred_alloc_mut,
4050 => true,
40504051
4051 .pointer => self.castTag(.pointer).?.data.size == .One,
4052 .pointer => ty.castTag(.pointer).?.data.size == .One,
40524053
4053 else => false,
4054 };
4054 else => false,
4055 },
4056 else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
4057 .ptr_type => |ptr_info| ptr_info.size == .One,
4058 else => false,
4059 },
4060 }
40554061 }
40564062
40574063 /// Asserts `ty` is a pointer.
......@@ -6142,6 +6148,11 @@ pub const Type = struct {
61426148 }
61436149
61446150 pub fn declSrcLocOrNull(ty: Type, mod: *Module) ?Module.SrcLoc {
6151 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
6152 .struct_type => @panic("TODO"),
6153 .union_type => @panic("TODO"),
6154 else => return null,
6155 };
61456156 switch (ty.tag()) {
61466157 .enum_full, .enum_nonexhaustive => {
61476158 const enum_full = ty.cast(Payload.EnumFull).?.data;