Commit cbf304d8c3

Jacob Young <jacobly0@users.noreply.github.com>
2023-05-21 00:24:42
InternPool: fix coersion issues
1 parent 25cd4bb
Changed files (4)
src/codegen/llvm.zig
@@ -3357,7 +3357,7 @@ pub const DeclGen = struct {
                     }),
                 },
                 else => switch (mod.intern_pool.indexToKey(tv.val.ip_index)) {
-                    .int => |int| return lowerIntAsPtr(dg, int),
+                    .int => |int| return dg.lowerIntAsPtr(int),
                     .ptr => |ptr| {
                         const ptr_val = switch (ptr.addr) {
                             .@"var" => |@"var"| ptr: {
@@ -3376,7 +3376,7 @@ pub const DeclGen = struct {
                             },
                             .decl => |decl| try lowerDeclRefValue(dg, tv, 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) {
                             .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 {
         const mod = dg.module;
         const target = mod.getTarget();
-        if (ptr_val.ip_index != .none) switch (mod.intern_pool.indexToKey(ptr_val.ip_index)) {
-            .int => |int| return lowerIntAsPtr(dg, int),
+        if (ptr_val.ip_index != .none) return switch (mod.intern_pool.indexToKey(ptr_val.ip_index)) {
+            .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,
         };
         switch (ptr_val.tag()) {
src/InternPool.zig
@@ -2584,9 +2584,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
 
         .extern_func => @panic("TODO"),
 
-        .ptr => |ptr| switch (ip.items.items(.tag)[@enumToInt(ptr.ty)]) {
-            .type_pointer => {
-                assert(ptr.len == .none);
+        .ptr => |ptr| switch (ptr.len) {
+            .none => {
+                assert(ip.indexToKey(ptr.ty).ptr_type.size != .Slice);
                 switch (ptr.addr) {
                     .@"var" => |@"var"| ip.items.appendAssumeCapacity(.{
                         .tag = .ptr_var,
@@ -2626,11 +2626,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
                     }),
                 }
             },
-            .type_slice => {
-                assert(ptr.len != .none);
+            else => {
+                assert(ip.indexToKey(ptr.ty).ptr_type.size == .Slice);
                 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;
+                assert(ip.indexToKey(new_key.ptr.ty).ptr_type.size == .Many);
                 const ptr_index = try get(ip, gpa, new_key);
                 try ip.items.ensureUnusedCapacity(gpa, 1);
                 ip.items.appendAssumeCapacity(.{
@@ -2641,7 +2642,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
                     }),
                 });
             },
-            else => unreachable,
         },
 
         .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.
 /// Only some combinations are allowed:
+/// * identity coercion
 /// * int <=> int
 /// * int <=> enum
 /// * ptr <=> ptr
 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)) {
         .int => |int| switch (ip.indexToKey(new_ty)) {
             .enum_type => return ip.get(gpa, .{ .enum_tag = .{
src/Sema.zig
@@ -7836,7 +7836,7 @@ fn resolveGenericInstantiationType(
             const arg_val = (child_sema.resolveMaybeUndefValAllowVariables(arg) catch unreachable).?;
             child_sema.comptime_args[arg_i] = .{
                 .ty = arg_ty,
-                .val = try arg_val.copy(new_decl_arena_allocator),
+                .val = (try arg_val.intern(arg_ty, mod)).toValue(),
             };
         } else {
             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});
                                 const new_decl = try anon_decl.finish(
                                     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
                                 );
                                 break :v try Value.Tag.slice.create(fields_anon_decl.arena(), .{
src/value.zig
@@ -603,7 +603,7 @@ pub const Value = struct {
     }
 
     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()) {
             .slice => {
                 const pl = val.castTag(.slice).?.data;
@@ -2769,9 +2769,18 @@ pub const Value = struct {
         mod: *Module,
     ) Allocator.Error!Value {
         const elem_ty = ty.elemType2(mod);
-        const ptr_val = switch (val.tag()) {
-            .slice => val.castTag(.slice).?.data.ptr,
-            else => val,
+        const ptr_val = switch (val.ip_index) {
+            .none => switch (val.tag()) {
+                .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) {