mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
InternPool: fix coersion issues
This commit is contained in:
parent
25cd4bb3c9
commit
cbf304d8c3
4 changed files with 34 additions and 17 deletions
|
|
@ -2584,9 +2584,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
|
||||||
|
|
||||||
.extern_func => @panic("TODO"),
|
.extern_func => @panic("TODO"),
|
||||||
|
|
||||||
.ptr => |ptr| switch (ip.items.items(.tag)[@enumToInt(ptr.ty)]) {
|
.ptr => |ptr| switch (ptr.len) {
|
||||||
.type_pointer => {
|
.none => {
|
||||||
assert(ptr.len == .none);
|
assert(ip.indexToKey(ptr.ty).ptr_type.size != .Slice);
|
||||||
switch (ptr.addr) {
|
switch (ptr.addr) {
|
||||||
.@"var" => |@"var"| ip.items.appendAssumeCapacity(.{
|
.@"var" => |@"var"| ip.items.appendAssumeCapacity(.{
|
||||||
.tag = .ptr_var,
|
.tag = .ptr_var,
|
||||||
|
|
@ -2626,11 +2626,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.type_slice => {
|
else => {
|
||||||
assert(ptr.len != .none);
|
assert(ip.indexToKey(ptr.ty).ptr_type.size == .Slice);
|
||||||
var new_key = key;
|
var new_key = key;
|
||||||
new_key.ptr.ty = @intToEnum(Index, ip.items.items(.data)[@enumToInt(ptr.ty)]);
|
new_key.ptr.ty = ip.slicePtrType(ptr.ty);
|
||||||
new_key.ptr.len = .none;
|
new_key.ptr.len = .none;
|
||||||
|
assert(ip.indexToKey(new_key.ptr.ty).ptr_type.size == .Many);
|
||||||
const ptr_index = try get(ip, gpa, new_key);
|
const ptr_index = try get(ip, gpa, new_key);
|
||||||
try ip.items.ensureUnusedCapacity(gpa, 1);
|
try ip.items.ensureUnusedCapacity(gpa, 1);
|
||||||
ip.items.appendAssumeCapacity(.{
|
ip.items.appendAssumeCapacity(.{
|
||||||
|
|
@ -2641,7 +2642,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
else => unreachable,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
.opt => |opt| {
|
.opt => |opt| {
|
||||||
|
|
@ -3465,10 +3465,12 @@ pub fn sliceLen(ip: InternPool, i: Index) Index {
|
||||||
|
|
||||||
/// Given an existing value, returns the same value but with the supplied type.
|
/// Given an existing value, returns the same value but with the supplied type.
|
||||||
/// Only some combinations are allowed:
|
/// Only some combinations are allowed:
|
||||||
|
/// * identity coercion
|
||||||
/// * int <=> int
|
/// * int <=> int
|
||||||
/// * int <=> enum
|
/// * int <=> enum
|
||||||
/// * ptr <=> ptr
|
/// * ptr <=> ptr
|
||||||
pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index {
|
pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index {
|
||||||
|
if (ip.typeOf(val) == new_ty) return val;
|
||||||
switch (ip.indexToKey(val)) {
|
switch (ip.indexToKey(val)) {
|
||||||
.int => |int| switch (ip.indexToKey(new_ty)) {
|
.int => |int| switch (ip.indexToKey(new_ty)) {
|
||||||
.enum_type => return ip.get(gpa, .{ .enum_tag = .{
|
.enum_type => return ip.get(gpa, .{ .enum_tag = .{
|
||||||
|
|
|
||||||
|
|
@ -7836,7 +7836,7 @@ fn resolveGenericInstantiationType(
|
||||||
const arg_val = (child_sema.resolveMaybeUndefValAllowVariables(arg) catch unreachable).?;
|
const arg_val = (child_sema.resolveMaybeUndefValAllowVariables(arg) catch unreachable).?;
|
||||||
child_sema.comptime_args[arg_i] = .{
|
child_sema.comptime_args[arg_i] = .{
|
||||||
.ty = arg_ty,
|
.ty = arg_ty,
|
||||||
.val = try arg_val.copy(new_decl_arena_allocator),
|
.val = (try arg_val.intern(arg_ty, mod)).toValue(),
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
child_sema.comptime_args[arg_i] = .{
|
child_sema.comptime_args[arg_i] = .{
|
||||||
|
|
@ -16537,7 +16537,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||||
try std.fmt.allocPrintZ(anon_decl.arena(), "{d}", .{i});
|
try std.fmt.allocPrintZ(anon_decl.arena(), "{d}", .{i});
|
||||||
const new_decl = try anon_decl.finish(
|
const new_decl = try anon_decl.finish(
|
||||||
try Type.array(anon_decl.arena(), bytes.len, Value.zero_u8, Type.u8, mod),
|
try Type.array(anon_decl.arena(), bytes.len, Value.zero_u8, Type.u8, mod),
|
||||||
try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
|
try Value.Tag.bytes.create(anon_decl.arena(), bytes.ptr[0 .. bytes.len + 1]),
|
||||||
0, // default alignment
|
0, // default alignment
|
||||||
);
|
);
|
||||||
break :v try Value.Tag.slice.create(fields_anon_decl.arena(), .{
|
break :v try Value.Tag.slice.create(fields_anon_decl.arena(), .{
|
||||||
|
|
|
||||||
|
|
@ -3357,7 +3357,7 @@ pub const DeclGen = struct {
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
else => switch (mod.intern_pool.indexToKey(tv.val.ip_index)) {
|
else => switch (mod.intern_pool.indexToKey(tv.val.ip_index)) {
|
||||||
.int => |int| return lowerIntAsPtr(dg, int),
|
.int => |int| return dg.lowerIntAsPtr(int),
|
||||||
.ptr => |ptr| {
|
.ptr => |ptr| {
|
||||||
const ptr_val = switch (ptr.addr) {
|
const ptr_val = switch (ptr.addr) {
|
||||||
.@"var" => |@"var"| ptr: {
|
.@"var" => |@"var"| ptr: {
|
||||||
|
|
@ -3376,7 +3376,7 @@ pub const DeclGen = struct {
|
||||||
},
|
},
|
||||||
.decl => |decl| try lowerDeclRefValue(dg, tv, decl),
|
.decl => |decl| try lowerDeclRefValue(dg, tv, decl),
|
||||||
.mut_decl => |mut_decl| try lowerDeclRefValue(dg, tv, mut_decl.decl),
|
.mut_decl => |mut_decl| try lowerDeclRefValue(dg, tv, mut_decl.decl),
|
||||||
.int => |int| lowerIntAsPtr(dg, mod.intern_pool.indexToKey(int).int),
|
.int => |int| dg.lowerIntAsPtr(mod.intern_pool.indexToKey(int).int),
|
||||||
};
|
};
|
||||||
switch (ptr.len) {
|
switch (ptr.len) {
|
||||||
.none => return ptr_val,
|
.none => return ptr_val,
|
||||||
|
|
@ -4084,8 +4084,14 @@ pub const DeclGen = struct {
|
||||||
fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, byte_aligned: bool) Error!*llvm.Value {
|
fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, byte_aligned: bool) Error!*llvm.Value {
|
||||||
const mod = dg.module;
|
const mod = dg.module;
|
||||||
const target = mod.getTarget();
|
const target = mod.getTarget();
|
||||||
if (ptr_val.ip_index != .none) switch (mod.intern_pool.indexToKey(ptr_val.ip_index)) {
|
if (ptr_val.ip_index != .none) return switch (mod.intern_pool.indexToKey(ptr_val.ip_index)) {
|
||||||
.int => |int| return lowerIntAsPtr(dg, int),
|
.int => |int| dg.lowerIntAsPtr(int),
|
||||||
|
.ptr => |ptr| switch (ptr.addr) {
|
||||||
|
.@"var" => |@"var"| dg.lowerParentPtrDecl(ptr_val, @"var".owner_decl),
|
||||||
|
.decl => |decl| dg.lowerParentPtrDecl(ptr_val, decl),
|
||||||
|
.mut_decl => |mut_decl| dg.lowerParentPtrDecl(ptr_val, mut_decl.decl),
|
||||||
|
.int => |int| dg.lowerIntAsPtr(mod.intern_pool.indexToKey(int).int),
|
||||||
|
},
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
switch (ptr_val.tag()) {
|
switch (ptr_val.tag()) {
|
||||||
|
|
|
||||||
|
|
@ -603,7 +603,7 @@ pub const Value = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn intern(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index {
|
pub fn intern(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index {
|
||||||
if (val.ip_index != .none) return val.ip_index;
|
if (val.ip_index != .none) return mod.intern_pool.getCoerced(mod.gpa, val.ip_index, ty.ip_index);
|
||||||
switch (val.tag()) {
|
switch (val.tag()) {
|
||||||
.slice => {
|
.slice => {
|
||||||
const pl = val.castTag(.slice).?.data;
|
const pl = val.castTag(.slice).?.data;
|
||||||
|
|
@ -2769,9 +2769,18 @@ pub const Value = struct {
|
||||||
mod: *Module,
|
mod: *Module,
|
||||||
) Allocator.Error!Value {
|
) Allocator.Error!Value {
|
||||||
const elem_ty = ty.elemType2(mod);
|
const elem_ty = ty.elemType2(mod);
|
||||||
const ptr_val = switch (val.tag()) {
|
const ptr_val = switch (val.ip_index) {
|
||||||
.slice => val.castTag(.slice).?.data.ptr,
|
.none => switch (val.tag()) {
|
||||||
else => val,
|
.slice => val.castTag(.slice).?.data.ptr,
|
||||||
|
else => val,
|
||||||
|
},
|
||||||
|
else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
|
||||||
|
.ptr => |ptr| switch (ptr.len) {
|
||||||
|
.none => val,
|
||||||
|
else => val.slicePtr(mod),
|
||||||
|
},
|
||||||
|
else => val,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (ptr_val.ip_index == .none and ptr_val.tag() == .elem_ptr) {
|
if (ptr_val.ip_index == .none and ptr_val.tag() == .elem_ptr) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue