| author | |
| committer | |
| log | e77dede87e8cff2679485aecf0d3af146595db3a |
| tree | 1e20a0b5b72790af73e56186d016749dcd92dbcf |
| parent | 264292f430668652818b30fe6cf5d8b434530c84 |
3 files changed, 51 insertions(+), 6 deletions(-)
src/Sema.zig+33-2| ... | ... | @@ -1898,10 +1898,14 @@ fn resolveMaybeUndefVal( |
| 1898 | 1898 | inst: Air.Inst.Ref, |
| 1899 | 1899 | ) CompileError!?Value { |
| 1900 | 1900 | const val = (try sema.resolveMaybeUndefValAllowVariables(inst)) orelse return null; |
| 1901 | switch (val.tag()) { | |
| 1902 | .variable => return null, | |
| 1901 | switch (val.ip_index) { | |
| 1903 | 1902 | .generic_poison => return error.GenericPoison, |
| 1904 | 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 | } |
| 1907 | 1911 | |
| ... | ... | @@ -33497,6 +33501,33 @@ fn typePtrOrOptionalPtrTy( |
| 33497 | 33501 | buf: *Type.Payload.ElemType, |
| 33498 | 33502 | ) !?Type { |
| 33499 | 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 | 33531 | switch (ty.tag()) { |
| 33501 | 33532 | .optional_single_const_pointer, |
| 33502 | 33533 | .optional_single_mut_pointer, |
src/type.zig+16-4| ... | ... | @@ -4319,8 +4319,20 @@ pub const Type = struct { |
| 4319 | 4319 | |
| 4320 | 4320 | /// Returns true if the type is optional and would be lowered to a single pointer |
| 4321 | 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 { | |
| 4323 | switch (self.tag()) { | |
| 4322 | /// This function must be kept in sync with `Sema.typePtrOrOptionalPtrTy`. | |
| 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 | 4336 | .optional_single_const_pointer, |
| 4325 | 4337 | .optional_single_mut_pointer, |
| 4326 | 4338 | .c_const_pointer, |
| ... | ... | @@ -4328,7 +4340,7 @@ pub const Type = struct { |
| 4328 | 4340 | => return true, |
| 4329 | 4341 | |
| 4330 | 4342 | .optional => { |
| 4331 | const child_ty = self.castTag(.optional).?.data; | |
| 4343 | const child_ty = ty.castTag(.optional).?.data; | |
| 4332 | 4344 | if (child_ty.zigTypeTag(mod) != .Pointer) return false; |
| 4333 | 4345 | const info = child_ty.ptrInfo().data; |
| 4334 | 4346 | switch (info.size) { |
| ... | ... | @@ -4337,7 +4349,7 @@ pub const Type = struct { |
| 4337 | 4349 | } |
| 4338 | 4350 | }, |
| 4339 | 4351 | |
| 4340 | .pointer => return self.castTag(.pointer).?.data.size == .C, | |
| 4352 | .pointer => return ty.castTag(.pointer).?.data.size == .C, | |
| 4341 | 4353 | |
| 4342 | 4354 | else => return false, |
| 4343 | 4355 | } |
src/value.zig+2| ... | ... | @@ -117,6 +117,8 @@ pub const Value = struct { |
| 117 | 117 | int_big_negative, |
| 118 | 118 | function, |
| 119 | 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 | 122 | variable, |
| 121 | 123 | /// A wrapper for values which are comptime-known but should |
| 122 | 124 | /// semantically be runtime-known. |