mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
InternPool: fix more crashes
This commit is contained in:
parent
66c4396854
commit
f2c716187c
8 changed files with 502 additions and 448 deletions
|
|
@ -650,8 +650,14 @@ pub const Key = union(enum) {
|
|||
.enum_type => |enum_type| std.hash.autoHash(hasher, enum_type.decl),
|
||||
|
||||
.variable => |variable| std.hash.autoHash(hasher, variable.decl),
|
||||
.extern_func => |extern_func| std.hash.autoHash(hasher, extern_func.decl),
|
||||
.func => |func| std.hash.autoHash(hasher, func.index),
|
||||
.extern_func => |extern_func| {
|
||||
std.hash.autoHash(hasher, extern_func.ty);
|
||||
std.hash.autoHash(hasher, extern_func.decl);
|
||||
},
|
||||
.func => |func| {
|
||||
std.hash.autoHash(hasher, func.ty);
|
||||
std.hash.autoHash(hasher, func.index);
|
||||
},
|
||||
|
||||
.int => |int| {
|
||||
// Canonicalize all integers by converting them to BigIntConst.
|
||||
|
|
@ -854,11 +860,11 @@ pub const Key = union(enum) {
|
|||
},
|
||||
.extern_func => |a_info| {
|
||||
const b_info = b.extern_func;
|
||||
return a_info.decl == b_info.decl;
|
||||
return a_info.ty == b_info.ty and a_info.decl == b_info.decl;
|
||||
},
|
||||
.func => |a_info| {
|
||||
const b_info = b.func;
|
||||
return a_info.index == b_info.index;
|
||||
return a_info.ty == b_info.ty and a_info.index == b_info.index;
|
||||
},
|
||||
|
||||
.ptr => |a_info| {
|
||||
|
|
@ -1340,8 +1346,8 @@ pub const Index = enum(u32) {
|
|||
float_c_longdouble_f128: struct { data: *Float128 },
|
||||
float_comptime_float: struct { data: *Float128 },
|
||||
variable: struct { data: *Variable },
|
||||
extern_func: struct { data: void },
|
||||
func: struct { data: void },
|
||||
extern_func: struct { data: *Key.ExternFunc },
|
||||
func: struct { data: *Key.Func },
|
||||
only_possible_value: DataIsIndex,
|
||||
union_value: struct { data: *Key.Union },
|
||||
bytes: struct { data: *Bytes },
|
||||
|
|
@ -3216,6 +3222,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
|
|||
|
||||
.opt => |opt| {
|
||||
assert(ip.isOptionalType(opt.ty));
|
||||
assert(opt.val == .none or ip.indexToKey(opt.ty).opt_type == ip.typeOf(opt.val));
|
||||
ip.items.appendAssumeCapacity(if (opt.val == .none) .{
|
||||
.tag = .opt_null,
|
||||
.data = @enumToInt(opt.ty),
|
||||
|
|
@ -3226,23 +3233,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
|
|||
},
|
||||
|
||||
.int => |int| b: {
|
||||
switch (int.ty) {
|
||||
.usize_type,
|
||||
.isize_type,
|
||||
.c_char_type,
|
||||
.c_short_type,
|
||||
.c_ushort_type,
|
||||
.c_int_type,
|
||||
.c_uint_type,
|
||||
.c_long_type,
|
||||
.c_ulong_type,
|
||||
.c_longlong_type,
|
||||
.c_ulonglong_type,
|
||||
.c_longdouble_type,
|
||||
.comptime_int_type,
|
||||
=> {},
|
||||
else => assert(ip.indexToKey(int.ty) == .int_type),
|
||||
}
|
||||
assert(ip.isIntegerType(int.ty));
|
||||
switch (int.storage) {
|
||||
.u64, .i64, .big_int => {},
|
||||
.lazy_align, .lazy_size => |lazy_ty| {
|
||||
|
|
@ -3425,13 +3416,16 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
|
|||
}
|
||||
},
|
||||
|
||||
.err => |err| ip.items.appendAssumeCapacity(.{
|
||||
.tag = .error_set_error,
|
||||
.data = try ip.addExtra(gpa, err),
|
||||
}),
|
||||
.err => |err| {
|
||||
assert(ip.isErrorSetType(err.ty));
|
||||
ip.items.appendAssumeCapacity(.{
|
||||
.tag = .error_set_error,
|
||||
.data = try ip.addExtra(gpa, err),
|
||||
});
|
||||
},
|
||||
|
||||
.error_union => |error_union| {
|
||||
assert(ip.indexToKey(error_union.ty) == .error_union_type);
|
||||
assert(ip.isErrorUnionType(error_union.ty));
|
||||
ip.items.appendAssumeCapacity(switch (error_union.val) {
|
||||
.err_name => |err_name| .{
|
||||
.tag = .error_union_error,
|
||||
|
|
@ -3456,9 +3450,8 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
|
|||
}),
|
||||
|
||||
.enum_tag => |enum_tag| {
|
||||
assert(enum_tag.ty != .none);
|
||||
assert(enum_tag.int != .none);
|
||||
|
||||
assert(ip.isEnumType(enum_tag.ty));
|
||||
assert(ip.indexToKey(enum_tag.int) == .int);
|
||||
ip.items.appendAssumeCapacity(.{
|
||||
.tag = .enum_tag,
|
||||
.data = try ip.addExtra(gpa, enum_tag),
|
||||
|
|
@ -4191,69 +4184,93 @@ pub fn sliceLen(ip: InternPool, i: Index) Index {
|
|||
/// * identity coercion
|
||||
/// * int <=> int
|
||||
/// * int <=> enum
|
||||
/// * enum_literal => enum
|
||||
/// * ptr <=> ptr
|
||||
/// * null_value => opt
|
||||
/// * payload => opt
|
||||
/// * error set <=> error set
|
||||
/// * error union <=> error union
|
||||
/// * error set => error union
|
||||
/// * payload => error union
|
||||
/// * fn <=> fn
|
||||
pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index {
|
||||
const old_ty = ip.typeOf(val);
|
||||
if (old_ty == new_ty) return val;
|
||||
switch (ip.indexToKey(val)) {
|
||||
.int => |int| switch (ip.indexToKey(new_ty)) {
|
||||
.simple_type => |simple_type| switch (simple_type) {
|
||||
.usize,
|
||||
.isize,
|
||||
.c_char,
|
||||
.c_short,
|
||||
.c_ushort,
|
||||
.c_int,
|
||||
.c_uint,
|
||||
.c_long,
|
||||
.c_ulong,
|
||||
.c_longlong,
|
||||
.c_ulonglong,
|
||||
.comptime_int,
|
||||
=> return getCoercedInts(ip, gpa, int, new_ty),
|
||||
else => {},
|
||||
},
|
||||
.int_type => return getCoercedInts(ip, gpa, int, new_ty),
|
||||
.enum_type => return ip.get(gpa, .{ .enum_tag = .{
|
||||
.extern_func => |extern_func| if (ip.isFunctionType(new_ty))
|
||||
return ip.get(gpa, .{ .extern_func = .{
|
||||
.ty = new_ty,
|
||||
.decl = extern_func.decl,
|
||||
.lib_name = extern_func.lib_name,
|
||||
} }),
|
||||
.func => |func| if (ip.isFunctionType(new_ty))
|
||||
return ip.get(gpa, .{ .func = .{
|
||||
.ty = new_ty,
|
||||
.index = func.index,
|
||||
} }),
|
||||
.int => |int| if (ip.isIntegerType(new_ty))
|
||||
return getCoercedInts(ip, gpa, int, new_ty)
|
||||
else if (ip.isEnumType(new_ty))
|
||||
return ip.get(gpa, .{ .enum_tag = .{
|
||||
.ty = new_ty,
|
||||
.int = val,
|
||||
} }),
|
||||
.enum_tag => |enum_tag| if (ip.isIntegerType(new_ty))
|
||||
return getCoercedInts(ip, gpa, ip.indexToKey(enum_tag.int).int, new_ty),
|
||||
.enum_literal => |enum_literal| switch (ip.indexToKey(new_ty)) {
|
||||
.enum_type => |enum_type| {
|
||||
const index = enum_type.nameIndex(ip, enum_literal).?;
|
||||
return ip.get(gpa, .{ .enum_tag = .{
|
||||
.ty = new_ty,
|
||||
.int = if (enum_type.values.len != 0)
|
||||
enum_type.values[index]
|
||||
else
|
||||
try ip.get(gpa, .{ .int = .{
|
||||
.ty = enum_type.tag_ty,
|
||||
.storage = .{ .u64 = index },
|
||||
} }),
|
||||
} });
|
||||
},
|
||||
else => {},
|
||||
},
|
||||
.enum_tag => |enum_tag| {
|
||||
// Assume new_ty is an integer type.
|
||||
return getCoercedInts(ip, gpa, ip.indexToKey(enum_tag.int).int, new_ty);
|
||||
},
|
||||
.ptr => |ptr| switch (ip.indexToKey(new_ty)) {
|
||||
.ptr_type => return ip.get(gpa, .{ .ptr = .{
|
||||
.ptr => |ptr| if (ip.isPointerType(new_ty))
|
||||
return ip.get(gpa, .{ .ptr = .{
|
||||
.ty = new_ty,
|
||||
.addr = ptr.addr,
|
||||
.len = ptr.len,
|
||||
} }),
|
||||
else => {},
|
||||
},
|
||||
.err => |err| switch (ip.indexToKey(new_ty)) {
|
||||
.error_set_type, .inferred_error_set_type => return ip.get(gpa, .{ .err = .{
|
||||
.err => |err| if (ip.isErrorSetType(new_ty))
|
||||
return ip.get(gpa, .{ .err = .{
|
||||
.ty = new_ty,
|
||||
.name = err.name,
|
||||
} })
|
||||
else if (ip.isErrorUnionType(new_ty))
|
||||
return ip.get(gpa, .{ .error_union = .{
|
||||
.ty = new_ty,
|
||||
.val = .{ .err_name = err.name },
|
||||
} }),
|
||||
.error_union => |error_union| if (ip.isErrorUnionType(new_ty))
|
||||
return ip.get(gpa, .{ .error_union = .{
|
||||
.ty = new_ty,
|
||||
.val = error_union.val,
|
||||
} }),
|
||||
else => {},
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
switch (ip.indexToKey(new_ty)) {
|
||||
.opt_type => |child_ty| switch (val) {
|
||||
.opt_type => |child_type| switch (val) {
|
||||
.null_value => return ip.get(gpa, .{ .opt = .{
|
||||
.ty = new_ty,
|
||||
.val = .none,
|
||||
} }),
|
||||
else => return ip.get(gpa, .{ .opt = .{
|
||||
.ty = new_ty,
|
||||
.val = try ip.getCoerced(gpa, val, child_ty),
|
||||
.val = try ip.getCoerced(gpa, val, child_type),
|
||||
} }),
|
||||
},
|
||||
.error_union_type => |error_union_type| return ip.get(gpa, .{ .error_union = .{
|
||||
.ty = new_ty,
|
||||
.val = .{ .payload = try ip.getCoerced(gpa, val, error_union_type.payload_type) },
|
||||
} }),
|
||||
else => {},
|
||||
}
|
||||
if (std.debug.runtime_safety) {
|
||||
|
|
@ -4271,33 +4288,24 @@ pub fn getCoercedInts(ip: *InternPool, gpa: Allocator, int: Key.Int, new_ty: Ind
|
|||
// big_int storage, the limbs would be invalidated before they are read.
|
||||
// Here we pre-reserve the limbs to ensure that the logic in `addInt` will
|
||||
// not use an invalidated limbs pointer.
|
||||
switch (int.storage) {
|
||||
.u64 => |x| return ip.get(gpa, .{ .int = .{
|
||||
.ty = new_ty,
|
||||
.storage = .{ .u64 = x },
|
||||
} }),
|
||||
.i64 => |x| return ip.get(gpa, .{ .int = .{
|
||||
.ty = new_ty,
|
||||
.storage = .{ .i64 = x },
|
||||
} }),
|
||||
|
||||
.big_int => |big_int| {
|
||||
const new_storage: Key.Int.Storage = switch (int.storage) {
|
||||
.u64, .i64, .lazy_align, .lazy_size => int.storage,
|
||||
.big_int => |big_int| storage: {
|
||||
const positive = big_int.positive;
|
||||
const limbs = ip.limbsSliceToIndex(big_int.limbs);
|
||||
// This line invalidates the limbs slice, but the indexes computed in the
|
||||
// previous line are still correct.
|
||||
try reserveLimbs(ip, gpa, @typeInfo(Int).Struct.fields.len + big_int.limbs.len);
|
||||
return ip.get(gpa, .{ .int = .{
|
||||
.ty = new_ty,
|
||||
.storage = .{ .big_int = .{
|
||||
.limbs = ip.limbsIndexToSlice(limbs),
|
||||
.positive = positive,
|
||||
} },
|
||||
} });
|
||||
break :storage .{ .big_int = .{
|
||||
.limbs = ip.limbsIndexToSlice(limbs),
|
||||
.positive = positive,
|
||||
} };
|
||||
},
|
||||
|
||||
.lazy_align, .lazy_size => unreachable,
|
||||
}
|
||||
};
|
||||
return ip.get(gpa, .{ .int = .{
|
||||
.ty = new_ty,
|
||||
.storage = new_storage,
|
||||
} });
|
||||
}
|
||||
|
||||
pub fn indexToStructType(ip: InternPool, val: Index) Module.Struct.OptionalIndex {
|
||||
|
|
@ -4345,25 +4353,68 @@ pub fn indexToInferredErrorSetType(ip: InternPool, val: Index) Module.Fn.Inferre
|
|||
return @intToEnum(Module.Fn.InferredErrorSet.Index, datas[@enumToInt(val)]).toOptional();
|
||||
}
|
||||
|
||||
/// includes .comptime_int_type
|
||||
pub fn isIntegerType(ip: InternPool, ty: Index) bool {
|
||||
return switch (ty) {
|
||||
.usize_type,
|
||||
.isize_type,
|
||||
.c_char_type,
|
||||
.c_short_type,
|
||||
.c_ushort_type,
|
||||
.c_int_type,
|
||||
.c_uint_type,
|
||||
.c_long_type,
|
||||
.c_ulong_type,
|
||||
.c_longlong_type,
|
||||
.c_ulonglong_type,
|
||||
.c_longdouble_type,
|
||||
.comptime_int_type,
|
||||
=> true,
|
||||
else => ip.indexToKey(ty) == .int_type,
|
||||
};
|
||||
}
|
||||
|
||||
/// does not include .enum_literal_type
|
||||
pub fn isEnumType(ip: InternPool, ty: Index) bool {
|
||||
return switch (ty) {
|
||||
.atomic_order_type,
|
||||
.atomic_rmw_op_type,
|
||||
.calling_convention_type,
|
||||
.address_space_type,
|
||||
.float_mode_type,
|
||||
.reduce_op_type,
|
||||
.call_modifier_type,
|
||||
=> true,
|
||||
else => ip.indexToKey(ty) == .enum_type,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isFunctionType(ip: InternPool, ty: Index) bool {
|
||||
return ip.indexToKey(ty) == .func_type;
|
||||
}
|
||||
|
||||
pub fn isPointerType(ip: InternPool, ty: Index) bool {
|
||||
const tags = ip.items.items(.tag);
|
||||
if (ty == .none) return false;
|
||||
return switch (tags[@enumToInt(ty)]) {
|
||||
.type_pointer, .type_slice => true,
|
||||
return ip.indexToKey(ty) == .ptr_type;
|
||||
}
|
||||
|
||||
pub fn isOptionalType(ip: InternPool, ty: Index) bool {
|
||||
return ip.indexToKey(ty) == .opt_type;
|
||||
}
|
||||
|
||||
/// includes .inferred_error_set_type
|
||||
pub fn isErrorSetType(ip: InternPool, ty: Index) bool {
|
||||
return ty == .anyerror_type or switch (ip.indexToKey(ty)) {
|
||||
.error_set_type, .inferred_error_set_type => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isOptionalType(ip: InternPool, ty: Index) bool {
|
||||
const tags = ip.items.items(.tag);
|
||||
if (ty == .none) return false;
|
||||
return tags[@enumToInt(ty)] == .type_optional;
|
||||
pub fn isInferredErrorSetType(ip: InternPool, ty: Index) bool {
|
||||
return ip.indexToKey(ty) == .inferred_error_set_type;
|
||||
}
|
||||
|
||||
pub fn isInferredErrorSetType(ip: InternPool, ty: Index) bool {
|
||||
const tags = ip.items.items(.tag);
|
||||
assert(ty != .none);
|
||||
return tags[@enumToInt(ty)] == .type_inferred_error_set;
|
||||
pub fn isErrorUnionType(ip: InternPool, ty: Index) bool {
|
||||
return ip.indexToKey(ty) == .error_union_type;
|
||||
}
|
||||
|
||||
/// The is only legal because the initializer is not part of the hash.
|
||||
|
|
|
|||
|
|
@ -6699,6 +6699,11 @@ pub fn intern(mod: *Module, key: InternPool.Key) Allocator.Error!InternPool.Inde
|
|||
return mod.intern_pool.get(mod.gpa, key);
|
||||
}
|
||||
|
||||
/// Shortcut for calling `intern_pool.getCoerced`.
|
||||
pub fn getCoerced(mod: *Module, val: Value, new_ty: Type) Allocator.Error!Value {
|
||||
return (try mod.intern_pool.getCoerced(mod.gpa, val.toIntern(), new_ty.toIntern())).toValue();
|
||||
}
|
||||
|
||||
pub fn intType(mod: *Module, signedness: std.builtin.Signedness, bits: u16) Allocator.Error!Type {
|
||||
const i = try intern(mod, .{ .int_type = .{
|
||||
.signedness = signedness,
|
||||
|
|
|
|||
218
src/Sema.zig
218
src/Sema.zig
|
|
@ -7821,7 +7821,6 @@ fn resolveGenericInstantiationType(
|
|||
const new_func_inst = try child_sema.resolveBody(&child_block, fn_info.param_body, fn_info.param_body_inst);
|
||||
const new_func_val = child_sema.resolveConstValue(&child_block, .unneeded, new_func_inst, undefined) catch unreachable;
|
||||
const new_func = new_func_val.getFunctionIndex(mod).unwrap().?;
|
||||
errdefer mod.destroyFunc(new_func);
|
||||
assert(new_func == new_module_func);
|
||||
|
||||
arg_i = 0;
|
||||
|
|
@ -10793,7 +10792,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
|
|||
check_range: {
|
||||
if (operand_ty.zigTypeTag(mod) == .Int) {
|
||||
const min_int = try operand_ty.minInt(mod);
|
||||
const max_int = try operand_ty.maxIntScalar(mod, Type.comptime_int);
|
||||
const max_int = try operand_ty.maxInt(mod, operand_ty);
|
||||
if (try range_set.spans(min_int, max_int, operand_ty)) {
|
||||
if (special_prong == .@"else") {
|
||||
return sema.fail(
|
||||
|
|
@ -11649,7 +11648,7 @@ const RangeSetUnhandledIterator = struct {
|
|||
fn init(sema: *Sema, ty: Type, range_set: RangeSet) !RangeSetUnhandledIterator {
|
||||
const mod = sema.mod;
|
||||
const min = try ty.minInt(mod);
|
||||
const max = try ty.maxIntScalar(mod, Type.comptime_int);
|
||||
const max = try ty.maxInt(mod, ty);
|
||||
|
||||
return RangeSetUnhandledIterator{
|
||||
.sema = sema,
|
||||
|
|
@ -15964,25 +15963,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
|||
}
|
||||
|
||||
const args_val = v: {
|
||||
const args_slice_ty = try mod.ptrType(.{
|
||||
.elem_type = param_info_ty.toIntern(),
|
||||
.size = .Slice,
|
||||
.is_const = true,
|
||||
const new_decl_ty = try mod.arrayType(.{
|
||||
.len = param_vals.len,
|
||||
.child = param_info_ty.toIntern(),
|
||||
});
|
||||
const new_decl = try params_anon_decl.finish(
|
||||
try mod.arrayType(.{
|
||||
.len = param_vals.len,
|
||||
.child = param_info_ty.toIntern(),
|
||||
.sentinel = .none,
|
||||
}),
|
||||
new_decl_ty,
|
||||
(try mod.intern(.{ .aggregate = .{
|
||||
.ty = args_slice_ty.toIntern(),
|
||||
.ty = new_decl_ty.toIntern(),
|
||||
.storage = .{ .elems = param_vals },
|
||||
} })).toValue(),
|
||||
0, // default alignment
|
||||
);
|
||||
break :v try mod.intern(.{ .ptr = .{
|
||||
.ty = args_slice_ty.toIntern(),
|
||||
.ty = (try mod.ptrType(.{
|
||||
.elem_type = param_info_ty.toIntern(),
|
||||
.size = .Slice,
|
||||
.is_const = true,
|
||||
})).toIntern(),
|
||||
.addr = .{ .decl = new_decl },
|
||||
.len = (try mod.intValue(Type.usize, param_vals.len)).toIntern(),
|
||||
} });
|
||||
|
|
@ -16214,7 +16212,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
|||
};
|
||||
return sema.addConstant(type_info_ty, (try mod.intern(.{ .un = .{
|
||||
.ty = type_info_ty.toIntern(),
|
||||
.tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.Vector))).toIntern(),
|
||||
.tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @enumToInt(std.builtin.TypeId.Optional))).toIntern(),
|
||||
.val = try mod.intern(.{ .aggregate = .{
|
||||
.ty = optional_field_ty.toIntern(),
|
||||
.storage = .{ .elems = &field_values },
|
||||
|
|
@ -16258,7 +16256,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
|||
const new_decl_ty = try mod.arrayType(.{
|
||||
.len = name.len,
|
||||
.child = .u8_type,
|
||||
.sentinel = .zero_u8,
|
||||
});
|
||||
const new_decl = try anon_decl.finish(
|
||||
new_decl_ty,
|
||||
|
|
@ -16269,8 +16266,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
|||
0, // default alignment
|
||||
);
|
||||
break :v try mod.intern(.{ .ptr = .{
|
||||
.ty = .slice_const_u8_sentinel_0_type,
|
||||
.ty = .slice_const_u8_type,
|
||||
.addr = .{ .decl = new_decl },
|
||||
.len = (try mod.intValue(Type.usize, name.len)).toIntern(),
|
||||
} });
|
||||
};
|
||||
|
||||
|
|
@ -16386,7 +16384,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
|||
const new_decl_ty = try mod.arrayType(.{
|
||||
.len = name.len,
|
||||
.child = .u8_type,
|
||||
.sentinel = .zero_u8,
|
||||
});
|
||||
const new_decl = try anon_decl.finish(
|
||||
new_decl_ty,
|
||||
|
|
@ -16397,8 +16394,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
|||
0, // default alignment
|
||||
);
|
||||
break :v try mod.intern(.{ .ptr = .{
|
||||
.ty = .slice_const_u8_sentinel_0_type,
|
||||
.ty = .slice_const_u8_type,
|
||||
.addr = .{ .decl = new_decl },
|
||||
.len = (try mod.intValue(Type.usize, name.len)).toIntern(),
|
||||
} });
|
||||
};
|
||||
|
||||
|
|
@ -16521,7 +16519,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
|||
const new_decl_ty = try mod.arrayType(.{
|
||||
.len = name.len,
|
||||
.child = .u8_type,
|
||||
.sentinel = .zero_u8,
|
||||
});
|
||||
const new_decl = try anon_decl.finish(
|
||||
new_decl_ty,
|
||||
|
|
@ -16532,8 +16529,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
|||
0, // default alignment
|
||||
);
|
||||
break :v try mod.intern(.{ .ptr = .{
|
||||
.ty = .slice_const_u8_sentinel_0_type,
|
||||
.ty = .slice_const_u8_type,
|
||||
.addr = .{ .decl = new_decl },
|
||||
.len = (try mod.intValue(Type.usize, name.len)).toIntern(),
|
||||
} });
|
||||
};
|
||||
|
||||
|
|
@ -16663,12 +16661,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
|||
const struct_type = switch (mod.intern_pool.indexToKey(struct_ty.toIntern())) {
|
||||
.anon_struct_type => |tuple| {
|
||||
struct_field_vals = try gpa.alloc(InternPool.Index, tuple.types.len);
|
||||
for (
|
||||
tuple.types,
|
||||
tuple.values,
|
||||
struct_field_vals,
|
||||
0..,
|
||||
) |field_ty, field_val, *struct_field_val, i| {
|
||||
for (struct_field_vals, 0..) |*struct_field_val, i| {
|
||||
const anon_struct_type = mod.intern_pool.indexToKey(struct_ty.toIntern()).anon_struct_type;
|
||||
const field_ty = anon_struct_type.types[i];
|
||||
const field_val = anon_struct_type.values[i];
|
||||
const name_val = v: {
|
||||
var anon_decl = try block.startAnonDecl();
|
||||
defer anon_decl.deinit();
|
||||
|
|
@ -16735,7 +16731,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
|||
const new_decl_ty = try mod.arrayType(.{
|
||||
.len = name.len,
|
||||
.child = .u8_type,
|
||||
.sentinel = .zero_u8,
|
||||
});
|
||||
const new_decl = try anon_decl.finish(
|
||||
new_decl_ty,
|
||||
|
|
@ -16746,7 +16741,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
|||
0, // default alignment
|
||||
);
|
||||
break :v try mod.intern(.{ .ptr = .{
|
||||
.ty = .slice_const_u8_sentinel_0_type,
|
||||
.ty = .slice_const_u8_type,
|
||||
.addr = .{ .decl = new_decl },
|
||||
.len = (try mod.intValue(Type.usize, name.len)).toIntern(),
|
||||
} });
|
||||
|
|
@ -16975,7 +16970,6 @@ fn typeInfoNamespaceDecls(
|
|||
const new_decl_ty = try mod.arrayType(.{
|
||||
.len = name.len,
|
||||
.child = .u8_type,
|
||||
.sentinel = .zero_u8,
|
||||
});
|
||||
const new_decl = try anon_decl.finish(
|
||||
new_decl_ty,
|
||||
|
|
@ -16986,7 +16980,7 @@ fn typeInfoNamespaceDecls(
|
|||
0, // default alignment
|
||||
);
|
||||
break :v try mod.intern(.{ .ptr = .{
|
||||
.ty = .slice_const_u8_sentinel_0_type,
|
||||
.ty = .slice_const_u8_type,
|
||||
.addr = .{ .decl = new_decl },
|
||||
.len = (try mod.intValue(Type.usize, name.len)).toIntern(),
|
||||
} });
|
||||
|
|
@ -20404,7 +20398,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
|
|||
.val = operand_val.toIntern(),
|
||||
} })).toValue());
|
||||
}
|
||||
return sema.addConstant(aligned_dest_ty, operand_val);
|
||||
return sema.addConstant(aligned_dest_ty, try mod.getCoerced(operand_val, aligned_dest_ty));
|
||||
}
|
||||
|
||||
try sema.requireRuntimeBlock(block, src, null);
|
||||
|
|
@ -22401,7 +22395,7 @@ fn analyzeMinMax(
|
|||
if (std.debug.runtime_safety) {
|
||||
assert(try sema.intFitsInType(val, refined_ty, null));
|
||||
}
|
||||
cur_minmax = try sema.addConstant(refined_ty, val);
|
||||
cur_minmax = try sema.addConstant(refined_ty, try mod.getCoerced(val, refined_ty));
|
||||
}
|
||||
|
||||
break :refined refined_ty;
|
||||
|
|
@ -22459,8 +22453,8 @@ fn analyzeMinMax(
|
|||
else => unreachable,
|
||||
};
|
||||
const max_val = switch (air_tag) {
|
||||
.min => try comptime_elem_ty.maxInt(mod, Type.comptime_int), // @min(ct, rt) <= ct
|
||||
.max => try unrefined_elem_ty.maxInt(mod, Type.comptime_int),
|
||||
.min => try comptime_elem_ty.maxInt(mod, comptime_elem_ty), // @min(ct, rt) <= ct
|
||||
.max => try unrefined_elem_ty.maxInt(mod, unrefined_elem_ty),
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
|
|
@ -23356,11 +23350,14 @@ fn zirBuiltinExtern(
|
|||
try mod.declareDeclDependency(sema.owner_decl_index, new_decl_index);
|
||||
try sema.ensureDeclAnalyzed(new_decl_index);
|
||||
|
||||
const ref = try mod.intern(.{ .ptr = .{
|
||||
.ty = (try mod.singleConstPtrType(ty)).toIntern(),
|
||||
return sema.addConstant(ty, try mod.getCoerced((try mod.intern(.{ .ptr = .{
|
||||
.ty = switch (mod.intern_pool.indexToKey(ty.toIntern())) {
|
||||
.ptr_type => ty.toIntern(),
|
||||
.opt_type => |child_type| child_type,
|
||||
else => unreachable,
|
||||
},
|
||||
.addr = .{ .decl = new_decl_index },
|
||||
} });
|
||||
return sema.addConstant(ty, ref.toValue());
|
||||
} })).toValue(), ty));
|
||||
}
|
||||
|
||||
fn zirWorkItem(
|
||||
|
|
@ -25887,13 +25884,7 @@ fn coerceExtra(
|
|||
var in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src);
|
||||
if (in_memory_result == .ok) {
|
||||
if (maybe_inst_val) |val| {
|
||||
if (val.ip_index == .none) {
|
||||
// Keep the comptime Value representation; take the new type.
|
||||
return sema.addConstant(dest_ty, val);
|
||||
} else {
|
||||
const new_val = try mod.intern_pool.getCoerced(sema.gpa, val.toIntern(), dest_ty.toIntern());
|
||||
return sema.addConstant(dest_ty, new_val.toValue());
|
||||
}
|
||||
return sema.addConstant(dest_ty, try mod.getCoerced(val, dest_ty));
|
||||
}
|
||||
try sema.requireRuntimeBlock(block, inst_src, null);
|
||||
return block.addBitCast(dest_ty, inst);
|
||||
|
|
@ -26269,8 +26260,7 @@ fn coerceExtra(
|
|||
if (!opts.report_err) return error.NotCoercible;
|
||||
return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(sema.mod), val.fmtValue(inst_ty, sema.mod) });
|
||||
}
|
||||
const new_val = try mod.intern_pool.getCoerced(sema.gpa, val.toIntern(), dest_ty.toIntern());
|
||||
return try sema.addConstant(dest_ty, new_val.toValue());
|
||||
return try sema.addConstant(dest_ty, try mod.getCoerced(val, dest_ty));
|
||||
}
|
||||
if (dest_ty.zigTypeTag(mod) == .ComptimeInt) {
|
||||
if (!opts.report_err) return error.NotCoercible;
|
||||
|
|
@ -27222,68 +27212,84 @@ fn coerceInMemoryAllowedFns(
|
|||
src_src: LazySrcLoc,
|
||||
) !InMemoryCoercionResult {
|
||||
const mod = sema.mod;
|
||||
const dest_info = mod.typeToFunc(dest_ty).?;
|
||||
const src_info = mod.typeToFunc(src_ty).?;
|
||||
|
||||
if (dest_info.is_var_args != src_info.is_var_args) {
|
||||
return InMemoryCoercionResult{ .fn_var_args = dest_info.is_var_args };
|
||||
}
|
||||
{
|
||||
const dest_info = mod.typeToFunc(dest_ty).?;
|
||||
const src_info = mod.typeToFunc(src_ty).?;
|
||||
|
||||
if (dest_info.is_generic != src_info.is_generic) {
|
||||
return InMemoryCoercionResult{ .fn_generic = dest_info.is_generic };
|
||||
}
|
||||
if (dest_info.is_var_args != src_info.is_var_args) {
|
||||
return InMemoryCoercionResult{ .fn_var_args = dest_info.is_var_args };
|
||||
}
|
||||
|
||||
if (dest_info.cc != src_info.cc) {
|
||||
return InMemoryCoercionResult{ .fn_cc = .{
|
||||
.actual = src_info.cc,
|
||||
.wanted = dest_info.cc,
|
||||
} };
|
||||
}
|
||||
if (dest_info.is_generic != src_info.is_generic) {
|
||||
return InMemoryCoercionResult{ .fn_generic = dest_info.is_generic };
|
||||
}
|
||||
|
||||
if (src_info.return_type != .noreturn_type) {
|
||||
const rt = try sema.coerceInMemoryAllowed(block, dest_info.return_type.toType(), src_info.return_type.toType(), false, target, dest_src, src_src);
|
||||
if (rt != .ok) {
|
||||
return InMemoryCoercionResult{ .fn_return_type = .{
|
||||
.child = try rt.dupe(sema.arena),
|
||||
.actual = src_info.return_type.toType(),
|
||||
.wanted = dest_info.return_type.toType(),
|
||||
if (dest_info.cc != src_info.cc) {
|
||||
return InMemoryCoercionResult{ .fn_cc = .{
|
||||
.actual = src_info.cc,
|
||||
.wanted = dest_info.cc,
|
||||
} };
|
||||
}
|
||||
|
||||
if (src_info.return_type != .noreturn_type) {
|
||||
const dest_return_type = dest_info.return_type.toType();
|
||||
const src_return_type = src_info.return_type.toType();
|
||||
const rt = try sema.coerceInMemoryAllowed(block, dest_return_type, src_return_type, false, target, dest_src, src_src);
|
||||
if (rt != .ok) {
|
||||
return InMemoryCoercionResult{ .fn_return_type = .{
|
||||
.child = try rt.dupe(sema.arena),
|
||||
.actual = dest_return_type,
|
||||
.wanted = src_return_type,
|
||||
} };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dest_info.param_types.len != src_info.param_types.len) {
|
||||
return InMemoryCoercionResult{ .fn_param_count = .{
|
||||
.actual = src_info.param_types.len,
|
||||
.wanted = dest_info.param_types.len,
|
||||
} };
|
||||
}
|
||||
const params_len = params_len: {
|
||||
const dest_info = mod.typeToFunc(dest_ty).?;
|
||||
const src_info = mod.typeToFunc(src_ty).?;
|
||||
|
||||
if (dest_info.noalias_bits != src_info.noalias_bits) {
|
||||
return InMemoryCoercionResult{ .fn_param_noalias = .{
|
||||
.actual = src_info.noalias_bits,
|
||||
.wanted = dest_info.noalias_bits,
|
||||
} };
|
||||
}
|
||||
if (dest_info.param_types.len != src_info.param_types.len) {
|
||||
return InMemoryCoercionResult{ .fn_param_count = .{
|
||||
.actual = src_info.param_types.len,
|
||||
.wanted = dest_info.param_types.len,
|
||||
} };
|
||||
}
|
||||
|
||||
for (dest_info.param_types, 0..) |dest_param_ty, i| {
|
||||
const src_param_ty = src_info.param_types[i].toType();
|
||||
if (dest_info.noalias_bits != src_info.noalias_bits) {
|
||||
return InMemoryCoercionResult{ .fn_param_noalias = .{
|
||||
.actual = src_info.noalias_bits,
|
||||
.wanted = dest_info.noalias_bits,
|
||||
} };
|
||||
}
|
||||
|
||||
const i_small = @intCast(u5, i);
|
||||
if (dest_info.paramIsComptime(i_small) != src_info.paramIsComptime(i_small)) {
|
||||
break :params_len dest_info.param_types.len;
|
||||
};
|
||||
|
||||
for (0..params_len) |param_i| {
|
||||
const dest_info = mod.typeToFunc(dest_ty).?;
|
||||
const src_info = mod.typeToFunc(src_ty).?;
|
||||
|
||||
const dest_param_ty = dest_info.param_types[param_i].toType();
|
||||
const src_param_ty = src_info.param_types[param_i].toType();
|
||||
|
||||
const param_i_small = @intCast(u5, param_i);
|
||||
if (dest_info.paramIsComptime(param_i_small) != src_info.paramIsComptime(param_i_small)) {
|
||||
return InMemoryCoercionResult{ .fn_param_comptime = .{
|
||||
.index = i,
|
||||
.wanted = dest_info.paramIsComptime(i_small),
|
||||
.index = param_i,
|
||||
.wanted = dest_info.paramIsComptime(param_i_small),
|
||||
} };
|
||||
}
|
||||
|
||||
// Note: Cast direction is reversed here.
|
||||
const param = try sema.coerceInMemoryAllowed(block, src_param_ty, dest_param_ty.toType(), false, target, dest_src, src_src);
|
||||
const param = try sema.coerceInMemoryAllowed(block, src_param_ty, dest_param_ty, false, target, dest_src, src_src);
|
||||
if (param != .ok) {
|
||||
return InMemoryCoercionResult{ .fn_param = .{
|
||||
.child = try param.dupe(sema.arena),
|
||||
.actual = src_param_ty,
|
||||
.wanted = dest_param_ty.toType(),
|
||||
.index = i,
|
||||
.wanted = dest_param_ty,
|
||||
.index = param_i,
|
||||
} };
|
||||
}
|
||||
}
|
||||
|
|
@ -28385,7 +28391,7 @@ fn beginComptimePtrLoad(
|
|||
};
|
||||
},
|
||||
.elem => |elem_ptr| blk: {
|
||||
const elem_ty = ptr.ty.toType().childType(mod);
|
||||
const elem_ty = ptr.ty.toType().elemType2(mod);
|
||||
var deref = try sema.beginComptimePtrLoad(block, src, elem_ptr.base.toValue(), null);
|
||||
|
||||
// This code assumes that elem_ptrs have been "flattened" in order for direct dereference
|
||||
|
|
@ -28678,11 +28684,10 @@ fn coerceCompatiblePtrs(
|
|||
return sema.fail(block, inst_src, "null pointer casted to type '{}'", .{dest_ty.fmt(sema.mod)});
|
||||
}
|
||||
// The comptime Value representation is compatible with both types.
|
||||
return sema.addConstant(dest_ty, (try mod.intern_pool.getCoerced(
|
||||
sema.gpa,
|
||||
try val.intern(inst_ty, mod),
|
||||
dest_ty.toIntern(),
|
||||
)).toValue());
|
||||
return sema.addConstant(
|
||||
dest_ty,
|
||||
try mod.getCoerced((try val.intern(inst_ty, mod)).toValue(), dest_ty),
|
||||
);
|
||||
}
|
||||
try sema.requireRuntimeBlock(block, inst_src, null);
|
||||
const inst_allows_zero = inst_ty.zigTypeTag(mod) != .Pointer or inst_ty.ptrAllowsZero(mod);
|
||||
|
|
@ -29390,9 +29395,13 @@ fn refValue(sema: *Sema, block: *Block, ty: Type, val: Value) !Value {
|
|||
|
||||
fn optRefValue(sema: *Sema, block: *Block, ty: Type, opt_val: ?Value) !Value {
|
||||
const mod = sema.mod;
|
||||
const ptr_anyopaque_ty = try mod.singleConstPtrType(Type.anyopaque);
|
||||
return (try mod.intern(.{ .opt = .{
|
||||
.ty = (try mod.optionalType((try mod.singleConstPtrType(Type.anyopaque)).toIntern())).toIntern(),
|
||||
.val = if (opt_val) |val| (try sema.refValue(block, ty, val)).toIntern() else .none,
|
||||
.ty = (try mod.optionalType(ptr_anyopaque_ty.toIntern())).toIntern(),
|
||||
.val = if (opt_val) |val| (try mod.getCoerced(
|
||||
try sema.refValue(block, ty, val),
|
||||
ptr_anyopaque_ty,
|
||||
)).toIntern() else .none,
|
||||
} })).toValue();
|
||||
}
|
||||
|
||||
|
|
@ -30051,11 +30060,10 @@ fn analyzeSlice(
|
|||
};
|
||||
|
||||
if (!new_ptr_val.isUndef(mod)) {
|
||||
return sema.addConstant(return_ty, (try mod.intern_pool.getCoerced(
|
||||
sema.gpa,
|
||||
try new_ptr_val.intern(new_ptr_ty, mod),
|
||||
return_ty.toIntern(),
|
||||
)).toValue());
|
||||
return sema.addConstant(return_ty, try mod.getCoerced(
|
||||
(try new_ptr_val.intern(new_ptr_ty, mod)).toValue(),
|
||||
return_ty,
|
||||
));
|
||||
}
|
||||
|
||||
// Special case: @as([]i32, undefined)[x..x]
|
||||
|
|
@ -34237,9 +34245,9 @@ fn enumHasInt(sema: *Sema, ty: Type, int: Value) CompileError!bool {
|
|||
// The `tagValueIndex` function call below relies on the type being the integer tag type.
|
||||
// `getCoerced` assumes the value will fit the new type.
|
||||
if (!(try sema.intFitsInType(int, enum_type.tag_ty.toType(), null))) return false;
|
||||
const int_coerced = try mod.intern_pool.getCoerced(sema.gpa, int.toIntern(), enum_type.tag_ty);
|
||||
const int_coerced = try mod.getCoerced(int, enum_type.tag_ty.toType());
|
||||
|
||||
return enum_type.tagValueIndex(&mod.intern_pool, int_coerced) != null;
|
||||
return enum_type.tagValueIndex(&mod.intern_pool, int_coerced.toIntern()) != null;
|
||||
}
|
||||
|
||||
fn intAddWithOverflow(
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ pub fn generateSymbol(
|
|||
|
||||
const mod = bin_file.options.module.?;
|
||||
var typed_value = arg_tv;
|
||||
switch (mod.intern_pool.indexToKey(typed_value.val.ip_index)) {
|
||||
switch (mod.intern_pool.indexToKey(typed_value.val.toIntern())) {
|
||||
.runtime_value => |rt| typed_value.val = rt.val.toValue(),
|
||||
else => {},
|
||||
}
|
||||
|
|
@ -204,7 +204,7 @@ pub fn generateSymbol(
|
|||
return .ok;
|
||||
}
|
||||
|
||||
switch (mod.intern_pool.indexToKey(typed_value.val.ip_index)) {
|
||||
switch (mod.intern_pool.indexToKey(typed_value.val.toIntern())) {
|
||||
.int_type,
|
||||
.ptr_type,
|
||||
.array_type,
|
||||
|
|
@ -282,7 +282,7 @@ pub fn generateSymbol(
|
|||
switch (try generateSymbol(bin_file, src_loc, .{
|
||||
.ty = payload_ty,
|
||||
.val = switch (error_union.val) {
|
||||
.err_name => try mod.intern(.{ .undef = payload_ty.ip_index }),
|
||||
.err_name => try mod.intern(.{ .undef = payload_ty.toIntern() }),
|
||||
.payload => |payload| payload,
|
||||
}.toValue(),
|
||||
}, code, debug_output, reloc_info)) {
|
||||
|
|
@ -315,7 +315,7 @@ pub fn generateSymbol(
|
|||
const int_tag_ty = try typed_value.ty.intTagType(mod);
|
||||
switch (try generateSymbol(bin_file, src_loc, .{
|
||||
.ty = int_tag_ty,
|
||||
.val = (try mod.intern_pool.getCoerced(mod.gpa, enum_tag.int, int_tag_ty.ip_index)).toValue(),
|
||||
.val = try mod.getCoerced(enum_tag.int.toValue(), int_tag_ty),
|
||||
}, code, debug_output, reloc_info)) {
|
||||
.ok => {},
|
||||
.fail => |em| return .{ .fail = em },
|
||||
|
|
@ -337,7 +337,7 @@ pub fn generateSymbol(
|
|||
switch (try lowerParentPtr(bin_file, src_loc, switch (ptr.len) {
|
||||
.none => typed_value.val,
|
||||
else => typed_value.val.slicePtr(mod),
|
||||
}.ip_index, code, debug_output, reloc_info)) {
|
||||
}.toIntern(), code, debug_output, reloc_info)) {
|
||||
.ok => {},
|
||||
.fail => |em| return .{ .fail = em },
|
||||
}
|
||||
|
|
@ -372,7 +372,7 @@ pub fn generateSymbol(
|
|||
} else {
|
||||
const padding = abi_size - (math.cast(usize, payload_type.abiSize(mod)) orelse return error.Overflow) - 1;
|
||||
if (payload_type.hasRuntimeBits(mod)) {
|
||||
const value = payload_val orelse (try mod.intern(.{ .undef = payload_type.ip_index })).toValue();
|
||||
const value = payload_val orelse (try mod.intern(.{ .undef = payload_type.toIntern() })).toValue();
|
||||
switch (try generateSymbol(bin_file, src_loc, .{
|
||||
.ty = payload_type,
|
||||
.val = value,
|
||||
|
|
@ -385,7 +385,7 @@ pub fn generateSymbol(
|
|||
try code.writer().writeByteNTimes(0, padding);
|
||||
}
|
||||
},
|
||||
.aggregate => |aggregate| switch (mod.intern_pool.indexToKey(typed_value.ty.ip_index)) {
|
||||
.aggregate => |aggregate| switch (mod.intern_pool.indexToKey(typed_value.ty.toIntern())) {
|
||||
.array_type => |array_type| {
|
||||
var index: u64 = 0;
|
||||
while (index < array_type.len) : (index += 1) {
|
||||
|
|
@ -850,7 +850,7 @@ pub fn genTypedValue(
|
|||
) CodeGenError!GenResult {
|
||||
const mod = bin_file.options.module.?;
|
||||
var typed_value = arg_tv;
|
||||
switch (mod.intern_pool.indexToKey(typed_value.val.ip_index)) {
|
||||
switch (mod.intern_pool.indexToKey(typed_value.val.toIntern())) {
|
||||
.runtime_value => |rt| typed_value.val = rt.val.toValue(),
|
||||
else => {},
|
||||
}
|
||||
|
|
@ -866,7 +866,7 @@ pub fn genTypedValue(
|
|||
const target = bin_file.options.target;
|
||||
const ptr_bits = target.ptrBitWidth();
|
||||
|
||||
if (!typed_value.ty.isSlice(mod)) switch (mod.intern_pool.indexToKey(typed_value.val.ip_index)) {
|
||||
if (!typed_value.ty.isSlice(mod)) switch (mod.intern_pool.indexToKey(typed_value.val.toIntern())) {
|
||||
.ptr => |ptr| switch (ptr.addr) {
|
||||
.decl => |decl| return genDeclRef(bin_file, src_loc, typed_value, decl),
|
||||
.mut_decl => |mut_decl| return genDeclRef(bin_file, src_loc, typed_value, mut_decl.decl),
|
||||
|
|
@ -879,12 +879,12 @@ pub fn genTypedValue(
|
|||
.Void => return GenResult.mcv(.none),
|
||||
.Pointer => switch (typed_value.ty.ptrSize(mod)) {
|
||||
.Slice => {},
|
||||
else => switch (typed_value.val.ip_index) {
|
||||
else => switch (typed_value.val.toIntern()) {
|
||||
.null_value => {
|
||||
return GenResult.mcv(.{ .immediate = 0 });
|
||||
},
|
||||
.none => {},
|
||||
else => switch (mod.intern_pool.indexToKey(typed_value.val.ip_index)) {
|
||||
else => switch (mod.intern_pool.indexToKey(typed_value.val.toIntern())) {
|
||||
.int => {
|
||||
return GenResult.mcv(.{ .immediate = typed_value.val.toUnsignedInt(mod) });
|
||||
},
|
||||
|
|
@ -916,7 +916,7 @@ pub fn genTypedValue(
|
|||
}
|
||||
},
|
||||
.Enum => {
|
||||
const enum_tag = mod.intern_pool.indexToKey(typed_value.val.ip_index).enum_tag;
|
||||
const enum_tag = mod.intern_pool.indexToKey(typed_value.val.toIntern()).enum_tag;
|
||||
const int_tag_ty = mod.intern_pool.typeOf(enum_tag.int);
|
||||
return genTypedValue(bin_file, src_loc, .{
|
||||
.ty = int_tag_ty.toType(),
|
||||
|
|
@ -924,7 +924,9 @@ pub fn genTypedValue(
|
|||
}, owner_decl_index);
|
||||
},
|
||||
.ErrorSet => {
|
||||
const err_name = mod.intern_pool.stringToSlice(mod.intern_pool.indexToKey(typed_value.val.ip_index).err.name);
|
||||
const err_name = mod.intern_pool.stringToSlice(
|
||||
mod.intern_pool.indexToKey(typed_value.val.toIntern()).err.name,
|
||||
);
|
||||
const global_error_set = mod.global_error_set;
|
||||
const error_index = global_error_set.get(err_name).?;
|
||||
return GenResult.mcv(.{ .immediate = error_index });
|
||||
|
|
|
|||
|
|
@ -2329,7 +2329,7 @@ pub const Object = struct {
|
|||
try param_di_types.append(try o.lowerDebugType(ptr_ty, .full));
|
||||
}
|
||||
|
||||
for (fn_info.param_types) |param_ty| {
|
||||
for (mod.typeToFunc(ty).?.param_types) |param_ty| {
|
||||
if (!param_ty.toType().hasRuntimeBitsIgnoreComptime(mod)) continue;
|
||||
|
||||
if (isByRef(param_ty.toType(), mod)) {
|
||||
|
|
|
|||
392
src/type.zig
392
src/type.zig
File diff suppressed because it is too large
Load diff
|
|
@ -345,7 +345,7 @@ pub const Value = struct {
|
|||
}
|
||||
|
||||
pub fn intern(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index {
|
||||
if (val.ip_index != .none) return mod.intern_pool.getCoerced(mod.gpa, val.toIntern(), ty.toIntern());
|
||||
if (val.ip_index != .none) return (try mod.getCoerced(val, ty)).toIntern();
|
||||
switch (val.tag()) {
|
||||
.eu_payload => {
|
||||
const pl = val.castTag(.eu_payload).?.data;
|
||||
|
|
@ -506,11 +506,7 @@ pub const Value = struct {
|
|||
else => unreachable,
|
||||
};
|
||||
},
|
||||
.enum_type => |enum_type| (try ip.getCoerced(
|
||||
mod.gpa,
|
||||
val.toIntern(),
|
||||
enum_type.tag_ty,
|
||||
)).toValue(),
|
||||
.enum_type => |enum_type| try mod.getCoerced(val, enum_type.tag_ty.toType()),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
|
@ -872,10 +868,15 @@ pub const Value = struct {
|
|||
.Packed => {
|
||||
var bits: u16 = 0;
|
||||
const fields = ty.structFields(mod).values();
|
||||
const field_vals = val.castTag(.aggregate).?.data;
|
||||
const storage = mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage;
|
||||
for (fields, 0..) |field, i| {
|
||||
const field_bits = @intCast(u16, field.ty.bitSize(mod));
|
||||
try field_vals[i].writeToPackedMemory(field.ty, mod, buffer, bit_offset + bits);
|
||||
const field_val = switch (storage) {
|
||||
.bytes => unreachable,
|
||||
.elems => |elems| elems[i],
|
||||
.repeated_elem => |elem| elem,
|
||||
};
|
||||
try field_val.toValue().writeToPackedMemory(field.ty, mod, buffer, bit_offset + bits);
|
||||
bits += field_bits;
|
||||
}
|
||||
},
|
||||
|
|
@ -2006,23 +2007,30 @@ pub const Value = struct {
|
|||
}
|
||||
|
||||
pub fn isPtrToThreadLocal(val: Value, mod: *Module) bool {
|
||||
return val.ip_index != .none and switch (mod.intern_pool.indexToKey(val.toIntern())) {
|
||||
.variable => false,
|
||||
else => val.isPtrToThreadLocalInner(mod),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isPtrToThreadLocalInner(val: Value, mod: *Module) bool {
|
||||
return val.ip_index != .none and switch (mod.intern_pool.indexToKey(val.toIntern())) {
|
||||
.variable => |variable| variable.is_threadlocal,
|
||||
.ptr => |ptr| switch (ptr.addr) {
|
||||
.decl => |decl_index| {
|
||||
const decl = mod.declPtr(decl_index);
|
||||
assert(decl.has_tv);
|
||||
return decl.val.isPtrToThreadLocal(mod);
|
||||
return decl.val.isPtrToThreadLocalInner(mod);
|
||||
},
|
||||
.mut_decl => |mut_decl| {
|
||||
const decl = mod.declPtr(mut_decl.decl);
|
||||
assert(decl.has_tv);
|
||||
return decl.val.isPtrToThreadLocal(mod);
|
||||
return decl.val.isPtrToThreadLocalInner(mod);
|
||||
},
|
||||
.int => false,
|
||||
.eu_payload, .opt_payload => |base_ptr| base_ptr.toValue().isPtrToThreadLocal(mod),
|
||||
.comptime_field => |comptime_field| comptime_field.toValue().isPtrToThreadLocal(mod),
|
||||
.elem, .field => |base_index| base_index.base.toValue().isPtrToThreadLocal(mod),
|
||||
.eu_payload, .opt_payload => |base_ptr| base_ptr.toValue().isPtrToThreadLocalInner(mod),
|
||||
.comptime_field => |comptime_field| comptime_field.toValue().isPtrToThreadLocalInner(mod),
|
||||
.elem, .field => |base_index| base_index.base.toValue().isPtrToThreadLocalInner(mod),
|
||||
},
|
||||
else => false,
|
||||
};
|
||||
|
|
@ -2045,7 +2053,18 @@ pub const Value = struct {
|
|||
else => unreachable,
|
||||
},
|
||||
.aggregate => |aggregate| (try mod.intern(.{ .aggregate = .{
|
||||
.ty = mod.intern_pool.typeOf(val.toIntern()),
|
||||
.ty = switch (mod.intern_pool.indexToKey(mod.intern_pool.typeOf(val.toIntern()))) {
|
||||
.array_type => |array_type| try mod.arrayType(.{
|
||||
.len = @intCast(u32, end - start),
|
||||
.child = array_type.child,
|
||||
.sentinel = if (end == array_type.len) array_type.sentinel else .none,
|
||||
}),
|
||||
.vector_type => |vector_type| try mod.vectorType(.{
|
||||
.len = @intCast(u32, end - start),
|
||||
.child = vector_type.child,
|
||||
}),
|
||||
else => unreachable,
|
||||
}.toIntern(),
|
||||
.storage = switch (aggregate.storage) {
|
||||
.bytes => |bytes| .{ .bytes = bytes[start..end] },
|
||||
.elems => |elems| .{ .elems = elems[start..end] },
|
||||
|
|
|
|||
|
|
@ -347,9 +347,15 @@ class TagAndPayload_SynthProvider:
|
|||
except: return -1
|
||||
def get_child_at_index(self, index): return (self.tag, self.payload)[index] if index in range(2) else None
|
||||
|
||||
def Inst_Ref_SummaryProvider(value, _=None):
|
||||
def Zir_Inst__Zir_Inst_Ref_SummaryProvider(value, _=None):
|
||||
members = value.type.enum_members
|
||||
return value if any(value.unsigned == member.unsigned for member in members) else 'instructions[%d]' % (value.unsigned - len(members))
|
||||
# ignore .var_args_param_type and .none
|
||||
return value if any(value.unsigned == member.unsigned for member in members) else 'instructions[%d]' % (value.unsigned + 2 - len(members))
|
||||
|
||||
def Air_Inst__Air_Inst_Ref_SummaryProvider(value, _=None):
|
||||
members = value.type.enum_members
|
||||
# ignore .none
|
||||
return value if any(value.unsigned == member.unsigned for member in members) else 'instructions[%d]' % (value.unsigned + 1 - len(members))
|
||||
|
||||
class Module_Decl__Module_Decl_Index_SynthProvider:
|
||||
def __init__(self, value, _=None): self.value = value
|
||||
|
|
@ -676,8 +682,9 @@ def __lldb_init_module(debugger, _=None):
|
|||
add(debugger, category='zig.stage2', type='Zir.Inst', identifier='TagAndPayload', synth=True, inline_children=True, summary=True)
|
||||
add(debugger, category='zig.stage2', regex=True, type=MultiArrayList_Entry('Zir\\.Inst'), identifier='TagAndPayload', synth=True, inline_children=True, summary=True)
|
||||
add(debugger, category='zig.stage2', regex=True, type='^Zir\\.Inst\\.Data\\.Data__struct_[1-9][0-9]*$', inline_children=True, summary=True)
|
||||
add(debugger, category='zig.stage2', type='Zir.Inst::Zir.Inst.Ref', identifier='Inst_Ref', summary=True)
|
||||
add(debugger, category='zig.stage2', type='Zir.Inst::Zir.Inst.Ref', summary=True)
|
||||
add(debugger, category='zig.stage2', type='Air.Inst', identifier='TagAndPayload', synth=True, inline_children=True, summary=True)
|
||||
add(debugger, category='zig.stage2', type='Air.Inst::Air.Inst.Ref', summary=True)
|
||||
add(debugger, category='zig.stage2', regex=True, type=MultiArrayList_Entry('Air\\.Inst'), identifier='TagAndPayload', synth=True, inline_children=True, summary=True)
|
||||
add(debugger, category='zig.stage2', regex=True, type='^Air\\.Inst\\.Data\\.Data__struct_[1-9][0-9]*$', inline_children=True, summary=True)
|
||||
add(debugger, category='zig.stage2', type='Module.Decl::Module.Decl.Index', synth=True)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue