mirror of
https://github.com/ziglang/zig.git
synced 2026-01-30 19:23:37 +00:00
InternPool: implement typePtrOrOptionalPtrTy
This commit is contained in:
parent
264292f430
commit
e77dede87e
35
src/Sema.zig
35
src/Sema.zig
@ -1898,10 +1898,14 @@ fn resolveMaybeUndefVal(
|
||||
inst: Air.Inst.Ref,
|
||||
) CompileError!?Value {
|
||||
const val = (try sema.resolveMaybeUndefValAllowVariables(inst)) orelse return null;
|
||||
switch (val.tag()) {
|
||||
.variable => return null,
|
||||
switch (val.ip_index) {
|
||||
.generic_poison => return error.GenericPoison,
|
||||
else => return val,
|
||||
.none => switch (val.tag()) {
|
||||
.variable => return null,
|
||||
.generic_poison => return error.GenericPoison,
|
||||
else => return val,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -33497,6 +33501,33 @@ fn typePtrOrOptionalPtrTy(
|
||||
buf: *Type.Payload.ElemType,
|
||||
) !?Type {
|
||||
const mod = sema.mod;
|
||||
|
||||
if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||
.ptr_type => |ptr_type| switch (ptr_type.size) {
|
||||
.Slice => return null,
|
||||
.C => return ptr_type.elem_type.toType(),
|
||||
.One, .Many => return ty,
|
||||
},
|
||||
.optional_type => |o| switch (mod.intern_pool.indexToKey(o.payload_type)) {
|
||||
.ptr_type => |ptr_type| switch (ptr_type.size) {
|
||||
.Slice, .C => return null,
|
||||
.Many, .One => {
|
||||
if (ptr_type.is_allowzero) return null;
|
||||
|
||||
// optionals of zero sized types behave like bools, not pointers
|
||||
const payload_ty = o.payload_type.toType();
|
||||
if ((try sema.typeHasOnePossibleValue(payload_ty)) != null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return payload_ty;
|
||||
},
|
||||
},
|
||||
else => return null,
|
||||
},
|
||||
else => return null,
|
||||
};
|
||||
|
||||
switch (ty.tag()) {
|
||||
.optional_single_const_pointer,
|
||||
.optional_single_mut_pointer,
|
||||
|
||||
20
src/type.zig
20
src/type.zig
@ -4319,8 +4319,20 @@ pub const Type = struct {
|
||||
|
||||
/// Returns true if the type is optional and would be lowered to a single pointer
|
||||
/// address value, using 0 for null. Note that this returns true for C pointers.
|
||||
pub fn isPtrLikeOptional(self: Type, mod: *const Module) bool {
|
||||
switch (self.tag()) {
|
||||
/// This function must be kept in sync with `Sema.typePtrOrOptionalPtrTy`.
|
||||
pub fn isPtrLikeOptional(ty: Type, mod: *const Module) bool {
|
||||
if (ty.ip_index != .none) return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||
.ptr_type => |ptr_type| ptr_type.size == .C,
|
||||
.optional_type => |o| switch (mod.intern_pool.indexToKey(o.payload_type)) {
|
||||
.ptr_type => |ptr_type| switch (ptr_type.size) {
|
||||
.Slice, .C => false,
|
||||
.Many, .One => !ptr_type.is_allowzero,
|
||||
},
|
||||
else => false,
|
||||
},
|
||||
else => false,
|
||||
};
|
||||
switch (ty.tag()) {
|
||||
.optional_single_const_pointer,
|
||||
.optional_single_mut_pointer,
|
||||
.c_const_pointer,
|
||||
@ -4328,7 +4340,7 @@ pub const Type = struct {
|
||||
=> return true,
|
||||
|
||||
.optional => {
|
||||
const child_ty = self.castTag(.optional).?.data;
|
||||
const child_ty = ty.castTag(.optional).?.data;
|
||||
if (child_ty.zigTypeTag(mod) != .Pointer) return false;
|
||||
const info = child_ty.ptrInfo().data;
|
||||
switch (info.size) {
|
||||
@ -4337,7 +4349,7 @@ pub const Type = struct {
|
||||
}
|
||||
},
|
||||
|
||||
.pointer => return self.castTag(.pointer).?.data.size == .C,
|
||||
.pointer => return ty.castTag(.pointer).?.data.size == .C,
|
||||
|
||||
else => return false,
|
||||
}
|
||||
|
||||
@ -117,6 +117,8 @@ pub const Value = struct {
|
||||
int_big_negative,
|
||||
function,
|
||||
extern_fn,
|
||||
/// A comptime-known pointer can point to the address of a global
|
||||
/// variable. The child element value in this case will have this tag.
|
||||
variable,
|
||||
/// A wrapper for values which are comptime-known but should
|
||||
/// semantically be runtime-known.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user