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...@@ -2086,7 +2086,7 @@ fn failWithUseOfAsync(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError
20862086
2087fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, object_ty: Type, field_name: []const u8) CompileError {2087fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, object_ty: Type, field_name: []const u8) CompileError {
2088 const mod = sema.mod;2088 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
2091 if (inner_ty.zigTypeTag(mod) == .Optional) opt: {2091 if (inner_ty.zigTypeTag(mod) == .Optional) opt: {
2092 var buf: Type.Payload.ElemType = undefined;2092 var buf: Type.Payload.ElemType = undefined;
...@@ -3412,8 +3412,9 @@ fn indexablePtrLen(...@@ -3412,8 +3412,9 @@ fn indexablePtrLen(
3412 src: LazySrcLoc,3412 src: LazySrcLoc,
3413 object: Air.Inst.Ref,3413 object: Air.Inst.Ref,
3414) CompileError!Air.Inst.Ref {3414) CompileError!Air.Inst.Ref {
3415 const mod = sema.mod;
3415 const object_ty = sema.typeOf(object);3416 const object_ty = sema.typeOf(object);
3416 const is_pointer_to = object_ty.isSinglePointer();3417 const is_pointer_to = object_ty.isSinglePointer(mod);
3417 const indexable_ty = if (is_pointer_to) object_ty.childType() else object_ty;3418 const indexable_ty = if (is_pointer_to) object_ty.childType() else object_ty;
3418 try checkIndexable(sema, block, src, indexable_ty);3419 try checkIndexable(sema, block, src, indexable_ty);
3419 return sema.fieldVal(block, src, object, "len", src);3420 return sema.fieldVal(block, src, object, "len", src);
...@@ -12764,12 +12765,12 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12764,12 +12765,12 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12764 .Pointer => try sema.resolveDefinedValue(block, rhs_src, rhs),12765 .Pointer => try sema.resolveDefinedValue(block, rhs_src, rhs),
12765 else => unreachable,12766 else => unreachable,
12766 }) |rhs_val| {12767 }) |rhs_val| {
12767 const lhs_sub_val = if (lhs_ty.isSinglePointer())12768 const lhs_sub_val = if (lhs_ty.isSinglePointer(mod))
12768 (try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).?12769 (try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).?
12769 else12770 else
12770 lhs_val;12771 lhs_val;
1277112772
12772 const rhs_sub_val = if (rhs_ty.isSinglePointer())12773 const rhs_sub_val = if (rhs_ty.isSinglePointer(mod))
12773 (try sema.pointerDeref(block, rhs_src, rhs_val, rhs_ty)).?12774 (try sema.pointerDeref(block, rhs_src, rhs_val, rhs_ty)).?
12774 else12775 else
12775 rhs_val;12776 rhs_val;
...@@ -13022,7 +13023,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13022,7 +13023,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13022 if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| {13023 if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| {
13023 const final_len_including_sent = result_len + @boolToInt(lhs_info.sentinel != null);13024 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))
13026 (try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).?13027 (try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).?
13027 else13028 else
13028 lhs_val;13029 lhs_val;
...@@ -17588,7 +17589,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -17588,7 +17589,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
17588 const elem_ty = blk: {17589 const elem_ty = blk: {
17589 const air_inst = try sema.resolveInst(extra.data.elem_type);17590 const air_inst = try sema.resolveInst(extra.data.elem_type);
17590 const ty = sema.analyzeAsType(block, elem_ty_src, air_inst) catch |err| {17591 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)) {
17592 try sema.errNote(block, elem_ty_src, sema.err.?, "use '.*' to dereference pointer", .{});17593 try sema.errNote(block, elem_ty_src, sema.err.?, "use '.*' to dereference pointer", .{});
17593 }17594 }
17594 return err;17595 return err;
...@@ -23902,7 +23903,7 @@ fn fieldVal(...@@ -23902,7 +23903,7 @@ fn fieldVal(
23902 // Zig allows dereferencing a single pointer during field lookup. Note that23903 // Zig allows dereferencing a single pointer during field lookup. Note that
23903 // we don't actually need to generate the dereference some field lookups, like the23904 // we don't actually need to generate the dereference some field lookups, like the
23904 // length of arrays and other comptime operations.23905 // 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
23907 const inner_ty = if (is_pointer_to)23908 const inner_ty = if (is_pointer_to)
23908 object_ty.childType()23909 object_ty.childType()
...@@ -24092,7 +24093,7 @@ fn fieldPtr(...@@ -24092,7 +24093,7 @@ fn fieldPtr(
24092 // Zig allows dereferencing a single pointer during field lookup. Note that24093 // Zig allows dereferencing a single pointer during field lookup. Note that
24093 // we don't actually need to generate the dereference some field lookups, like the24094 // we don't actually need to generate the dereference some field lookups, like the
24094 // length of arrays and other comptime operations.24095 // 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
24097 const inner_ty = if (is_pointer_to)24098 const inner_ty = if (is_pointer_to)
24098 object_ty.childType()24099 object_ty.childType()
...@@ -25622,7 +25623,7 @@ fn coerceExtra(...@@ -25622,7 +25623,7 @@ fn coerceExtra(
25622 // *T to *[1]T25623 // *T to *[1]T
25623 single_item: {25624 single_item: {
25624 if (dest_info.size != .One) break :single_item;25625 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;
25626 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;25627 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
25627 const ptr_elem_ty = inst_ty.childType();25628 const ptr_elem_ty = inst_ty.childType();
25628 const array_ty = dest_info.pointee_type;25629 const array_ty = dest_info.pointee_type;
...@@ -25639,7 +25640,7 @@ fn coerceExtra(...@@ -25639,7 +25640,7 @@ fn coerceExtra(
2563925640
25640 // Coercions where the source is a single pointer to an array.25641 // Coercions where the source is a single pointer to an array.
25641 src_array_ptr: {25642 src_array_ptr: {
25642 if (!inst_ty.isSinglePointer()) break :src_array_ptr;25643 if (!inst_ty.isSinglePointer(mod)) break :src_array_ptr;
25643 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;25644 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
25644 const array_ty = inst_ty.childType();25645 const array_ty = inst_ty.childType();
25645 if (array_ty.zigTypeTag(mod) != .Array) break :src_array_ptr;25646 if (array_ty.zigTypeTag(mod) != .Array) break :src_array_ptr;
...@@ -25794,7 +25795,7 @@ fn coerceExtra(...@@ -25794,7 +25795,7 @@ fn coerceExtra(
25794 .One => switch (dest_info.pointee_type.zigTypeTag(mod)) {25795 .One => switch (dest_info.pointee_type.zigTypeTag(mod)) {
25795 .Union => {25796 .Union => {
25796 // pointer to anonymous struct to pointer to union25797 // pointer to anonymous struct to pointer to union
25797 if (inst_ty.isSinglePointer() and25798 if (inst_ty.isSinglePointer(mod) and
25798 inst_ty.childType().isAnonStruct() and25799 inst_ty.childType().isAnonStruct() and
25799 sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))25800 sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
25800 {25801 {
...@@ -25803,7 +25804,7 @@ fn coerceExtra(...@@ -25803,7 +25804,7 @@ fn coerceExtra(
25803 },25804 },
25804 .Struct => {25805 .Struct => {
25805 // pointer to anonymous struct to pointer to struct25806 // pointer to anonymous struct to pointer to struct
25806 if (inst_ty.isSinglePointer() and25807 if (inst_ty.isSinglePointer(mod) and
25807 inst_ty.childType().isAnonStruct() and25808 inst_ty.childType().isAnonStruct() and
25808 sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))25809 sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
25809 {25810 {
...@@ -25815,7 +25816,7 @@ fn coerceExtra(...@@ -25815,7 +25816,7 @@ fn coerceExtra(
25815 },25816 },
25816 .Array => {25817 .Array => {
25817 // pointer to tuple to pointer to array25818 // pointer to tuple to pointer to array
25818 if (inst_ty.isSinglePointer() and25819 if (inst_ty.isSinglePointer(mod) and
25819 inst_ty.childType().isTuple() and25820 inst_ty.childType().isTuple() and
25820 sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))25821 sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
25821 {25822 {
...@@ -25834,7 +25835,7 @@ fn coerceExtra(...@@ -25834,7 +25835,7 @@ fn coerceExtra(
25834 );25835 );
25835 }25836 }
2583625837
25837 if (!inst_ty.isSinglePointer()) break :to_slice;25838 if (!inst_ty.isSinglePointer(mod)) break :to_slice;
25838 const inst_child_ty = inst_ty.childType();25839 const inst_child_ty = inst_ty.childType();
25839 if (!inst_child_ty.isTuple()) break :to_slice;25840 if (!inst_child_ty.isTuple()) break :to_slice;
2584025841
...@@ -30807,7 +30808,7 @@ fn resolvePeerTypes(...@@ -30807,7 +30808,7 @@ fn resolvePeerTypes(
30807 .Vector => continue,30808 .Vector => continue,
30808 else => {},30809 else => {},
30809 },30810 },
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) {
30811 if (.ok == try sema.coerceInMemoryAllowedFns(block, chosen_ty.childType(), candidate_ty, target, src, src)) {30812 if (.ok == try sema.coerceInMemoryAllowedFns(block, chosen_ty.childType(), candidate_ty, target, src, src)) {
30812 continue;30813 continue;
30813 }30814 }
src/codegen/c.zig+1-1
...@@ -3873,7 +3873,7 @@ fn airCmpOp(...@@ -3873,7 +3873,7 @@ fn airCmpOp(
3873 try reap(f, inst, &.{ data.lhs, data.rhs });3873 try reap(f, inst, &.{ data.lhs, data.rhs });
38743874
3875 const rhs_ty = f.typeOf(data.rhs);3875 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);
3877 const writer = f.object.writer();3877 const writer = f.object.writer();
3878 const local = try f.allocLocal(inst, inst_ty);3878 const local = try f.allocLocal(inst, inst_ty);
3879 const v = try Vectorize.start(f, inst, writer, lhs_ty);3879 const v = try Vectorize.start(f, inst, writer, lhs_ty);
src/codegen/llvm.zig+2-2
...@@ -5929,7 +5929,7 @@ pub const FuncGen = struct {...@@ -5929,7 +5929,7 @@ pub const FuncGen = struct {
5929 const base_ptr = try self.resolveInst(bin_op.lhs);5929 const base_ptr = try self.resolveInst(bin_op.lhs);
5930 const rhs = try self.resolveInst(bin_op.rhs);5930 const rhs = try self.resolveInst(bin_op.rhs);
5931 // TODO: when we go fully opaque pointers in LLVM 16 we can remove this branch5931 // 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: {
5933 // If this is a single-item pointer to an array, we need another index in the GEP.5933 // If this is a single-item pointer to an array, we need another index in the GEP.
5934 const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };5934 const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };
5935 break :ptr self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");5935 break :ptr self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
...@@ -5962,7 +5962,7 @@ pub const FuncGen = struct {...@@ -5962,7 +5962,7 @@ pub const FuncGen = struct {
5962 if (elem_ptr.ptrInfo().data.vector_index != .none) return base_ptr;5962 if (elem_ptr.ptrInfo().data.vector_index != .none) return base_ptr;
59635963
5964 const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty);5964 const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty);
5965 if (ptr_ty.isSinglePointer()) {5965 if (ptr_ty.isSinglePointer(mod)) {
5966 // If this is a single-item pointer to an array, we need another index in the GEP.5966 // If this is a single-item pointer to an array, we need another index in the GEP.
5967 const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };5967 const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };
5968 return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");5968 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 {...@@ -4039,19 +4039,25 @@ pub const Type = struct {
4039 }4039 }
4040 }4040 }
40414041
4042 pub fn isSinglePointer(self: Type) bool {4042 pub fn isSinglePointer(ty: Type, mod: *const Module) bool {
4043 return switch (self.tag()) {4043 switch (ty.ip_index) {
4044 .single_const_pointer,4044 .none => return switch (ty.tag()) {
4045 .single_mut_pointer,4045 .single_const_pointer,
4046 .single_const_pointer_to_comptime_int,4046 .single_mut_pointer,
4047 .inferred_alloc_const,4047 .single_const_pointer_to_comptime_int,
4048 .inferred_alloc_mut,4048 .inferred_alloc_const,
4049 => true,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 else => false,
4054 };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 }
4055 }4061 }
40564062
4057 /// Asserts `ty` is a pointer.4063 /// Asserts `ty` is a pointer.
...@@ -6142,6 +6148,11 @@ pub const Type = struct {...@@ -6142,6 +6148,11 @@ pub const Type = struct {
6142 }6148 }
61436149
6144 pub fn declSrcLocOrNull(ty: Type, mod: *Module) ?Module.SrcLoc {6150 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 };
6145 switch (ty.tag()) {6156 switch (ty.tag()) {
6146 .enum_full, .enum_nonexhaustive => {6157 .enum_full, .enum_nonexhaustive => {
6147 const enum_full = ty.cast(Payload.EnumFull).?.data;6158 const enum_full = ty.cast(Payload.EnumFull).?.data;