authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-03 13:38:59-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:40:03-07:00
loge77dede87e8cff2679485aecf0d3af146595db3a
tree1e20a0b5b72790af73e56186d016749dcd92dbcf
parent264292f430668652818b30fe6cf5d8b434530c84

InternPool: implement typePtrOrOptionalPtrTy


3 files changed, 51 insertions(+), 6 deletions(-)

src/Sema.zig+33-2
...@@ -1898,10 +1898,14 @@ fn resolveMaybeUndefVal(...@@ -1898,10 +1898,14 @@ fn resolveMaybeUndefVal(
1898 inst: Air.Inst.Ref,1898 inst: Air.Inst.Ref,
1899) CompileError!?Value {1899) CompileError!?Value {
1900 const val = (try sema.resolveMaybeUndefValAllowVariables(inst)) orelse return null;1900 const val = (try sema.resolveMaybeUndefValAllowVariables(inst)) orelse return null;
1901 switch (val.tag()) {1901 switch (val.ip_index) {
1902 .variable => return null,
1903 .generic_poison => return error.GenericPoison,1902 .generic_poison => return error.GenericPoison,
1904 else => return val,1903 else => return val,
1904 .none => switch (val.tag()) {
1905 .variable => return null,
1906 .generic_poison => return error.GenericPoison,
1907 else => return val,
1908 },
1905 }1909 }
1906}1910}
19071911
...@@ -33497,6 +33501,33 @@ fn typePtrOrOptionalPtrTy(...@@ -33497,6 +33501,33 @@ fn typePtrOrOptionalPtrTy(
33497 buf: *Type.Payload.ElemType,33501 buf: *Type.Payload.ElemType,
33498) !?Type {33502) !?Type {
33499 const mod = sema.mod;33503 const mod = sema.mod;
33504
33505 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
33506 .ptr_type => |ptr_type| switch (ptr_type.size) {
33507 .Slice => return null,
33508 .C => return ptr_type.elem_type.toType(),
33509 .One, .Many => return ty,
33510 },
33511 .optional_type => |o| switch (mod.intern_pool.indexToKey(o.payload_type)) {
33512 .ptr_type => |ptr_type| switch (ptr_type.size) {
33513 .Slice, .C => return null,
33514 .Many, .One => {
33515 if (ptr_type.is_allowzero) return null;
33516
33517 // optionals of zero sized types behave like bools, not pointers
33518 const payload_ty = o.payload_type.toType();
33519 if ((try sema.typeHasOnePossibleValue(payload_ty)) != null) {
33520 return null;
33521 }
33522
33523 return payload_ty;
33524 },
33525 },
33526 else => return null,
33527 },
33528 else => return null,
33529 };
33530
33500 switch (ty.tag()) {33531 switch (ty.tag()) {
33501 .optional_single_const_pointer,33532 .optional_single_const_pointer,
33502 .optional_single_mut_pointer,33533 .optional_single_mut_pointer,
src/type.zig+16-4
...@@ -4319,8 +4319,20 @@ pub const Type = struct {...@@ -4319,8 +4319,20 @@ pub const Type = struct {
43194319
4320 /// Returns true if the type is optional and would be lowered to a single pointer4320 /// Returns true if the type is optional and would be lowered to a single pointer
4321 /// address value, using 0 for null. Note that this returns true for C pointers.4321 /// address value, using 0 for null. Note that this returns true for C pointers.
4322 pub fn isPtrLikeOptional(self: Type, mod: *const Module) bool {4322 /// This function must be kept in sync with `Sema.typePtrOrOptionalPtrTy`.
4323 switch (self.tag()) {4323 pub fn isPtrLikeOptional(ty: Type, mod: *const Module) bool {
4324 if (ty.ip_index != .none) return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
4325 .ptr_type => |ptr_type| ptr_type.size == .C,
4326 .optional_type => |o| switch (mod.intern_pool.indexToKey(o.payload_type)) {
4327 .ptr_type => |ptr_type| switch (ptr_type.size) {
4328 .Slice, .C => false,
4329 .Many, .One => !ptr_type.is_allowzero,
4330 },
4331 else => false,
4332 },
4333 else => false,
4334 };
4335 switch (ty.tag()) {
4324 .optional_single_const_pointer,4336 .optional_single_const_pointer,
4325 .optional_single_mut_pointer,4337 .optional_single_mut_pointer,
4326 .c_const_pointer,4338 .c_const_pointer,
...@@ -4328,7 +4340,7 @@ pub const Type = struct {...@@ -4328,7 +4340,7 @@ pub const Type = struct {
4328 => return true,4340 => return true,
43294341
4330 .optional => {4342 .optional => {
4331 const child_ty = self.castTag(.optional).?.data;4343 const child_ty = ty.castTag(.optional).?.data;
4332 if (child_ty.zigTypeTag(mod) != .Pointer) return false;4344 if (child_ty.zigTypeTag(mod) != .Pointer) return false;
4333 const info = child_ty.ptrInfo().data;4345 const info = child_ty.ptrInfo().data;
4334 switch (info.size) {4346 switch (info.size) {
...@@ -4337,7 +4349,7 @@ pub const Type = struct {...@@ -4337,7 +4349,7 @@ pub const Type = struct {
4337 }4349 }
4338 },4350 },
43394351
4340 .pointer => return self.castTag(.pointer).?.data.size == .C,4352 .pointer => return ty.castTag(.pointer).?.data.size == .C,
43414353
4342 else => return false,4354 else => return false,
4343 }4355 }
src/value.zig+2
...@@ -117,6 +117,8 @@ pub const Value = struct {...@@ -117,6 +117,8 @@ pub const Value = struct {
117 int_big_negative,117 int_big_negative,
118 function,118 function,
119 extern_fn,119 extern_fn,
120 /// A comptime-known pointer can point to the address of a global
121 /// variable. The child element value in this case will have this tag.
120 variable,122 variable,
121 /// A wrapper for values which are comptime-known but should123 /// A wrapper for values which are comptime-known but should
122 /// semantically be runtime-known.124 /// semantically be runtime-known.