Commit c473594114

Jacob Young <jacobly0@users.noreply.github.com>
2023-05-20 05:16:36
Sema: port reify struct access to use InternPool
1 parent f8b6eb6
Changed files (2)
src/Sema.zig
@@ -18805,6 +18805,7 @@ fn zirReify(
     const target = mod.getTarget();
     const tag_index = type_info_ty.unionTagFieldIndex(union_val.tag, mod).?;
     if (try union_val.val.anyUndef(mod)) return sema.failWithUseOfUndef(block, src);
+    const ip = &mod.intern_pool;
     switch (@intToEnum(std.builtin.TypeId, tag_index)) {
         .Type => return Air.Inst.Ref.type_type,
         .Void => return Air.Inst.Ref.void_type,
@@ -18817,10 +18818,12 @@ fn zirReify(
         .AnyFrame => return sema.failWithUseOfAsync(block, src),
         .EnumLiteral => return Air.Inst.Ref.enum_literal_type,
         .Int => {
-            const struct_val = union_val.val.castTag(.aggregate).?.data;
-            // TODO use reflection instead of magic numbers here
-            const signedness_val = struct_val[0];
-            const bits_val = struct_val[1];
+            const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
+            const signedness_index = fields.getIndex("signedness").?;
+            const bits_index = fields.getIndex("bits").?;
+
+            const signedness_val = try union_val.val.fieldValue(fields.values()[signedness_index].ty, mod, signedness_index);
+            const bits_val = try union_val.val.fieldValue(fields.values()[bits_index].ty, mod, bits_index);
 
             const signedness = mod.toEnum(std.builtin.Signedness, signedness_val);
             const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
@@ -18828,10 +18831,12 @@ fn zirReify(
             return sema.addType(ty);
         },
         .Vector => {
-            const struct_val = union_val.val.castTag(.aggregate).?.data;
-            // TODO use reflection instead of magic numbers here
-            const len_val = struct_val[0];
-            const child_val = struct_val[1];
+            const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
+            const len_index = fields.getIndex("len").?;
+            const child_index = fields.getIndex("child").?;
+
+            const len_val = try union_val.val.fieldValue(fields.values()[len_index].ty, mod, len_index);
+            const child_val = try union_val.val.fieldValue(fields.values()[child_index].ty, mod, child_index);
 
             const len = @intCast(u32, len_val.toUnsignedInt(mod));
             const child_ty = child_val.toType();
@@ -18845,10 +18850,10 @@ fn zirReify(
             return sema.addType(ty);
         },
         .Float => {
-            const struct_val = union_val.val.castTag(.aggregate).?.data;
-            // TODO use reflection instead of magic numbers here
-            // bits: comptime_int,
-            const bits_val = struct_val[0];
+            const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
+            const bits_index = fields.getIndex("bits").?;
+
+            const bits_val = try union_val.val.fieldValue(fields.values()[bits_index].ty, mod, bits_index);
 
             const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
             const ty = switch (bits) {
@@ -18862,16 +18867,24 @@ fn zirReify(
             return sema.addType(ty);
         },
         .Pointer => {
-            const struct_val = union_val.val.castTag(.aggregate).?.data;
-            // TODO use reflection instead of magic numbers here
-            const size_val = struct_val[0];
-            const is_const_val = struct_val[1];
-            const is_volatile_val = struct_val[2];
-            const alignment_val = struct_val[3];
-            const address_space_val = struct_val[4];
-            const child_val = struct_val[5];
-            const is_allowzero_val = struct_val[6];
-            const sentinel_val = struct_val[7];
+            const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
+            const size_index = fields.getIndex("size").?;
+            const is_const_index = fields.getIndex("is_const").?;
+            const is_volatile_index = fields.getIndex("is_volatile").?;
+            const alignment_index = fields.getIndex("alignment").?;
+            const address_space_index = fields.getIndex("address_space").?;
+            const child_index = fields.getIndex("child").?;
+            const is_allowzero_index = fields.getIndex("is_allowzero").?;
+            const sentinel_index = fields.getIndex("sentinel").?;
+
+            const size_val = try union_val.val.fieldValue(fields.values()[size_index].ty, mod, size_index);
+            const is_const_val = try union_val.val.fieldValue(fields.values()[is_const_index].ty, mod, is_const_index);
+            const is_volatile_val = try union_val.val.fieldValue(fields.values()[is_volatile_index].ty, mod, is_volatile_index);
+            const alignment_val = try union_val.val.fieldValue(fields.values()[alignment_index].ty, mod, alignment_index);
+            const address_space_val = try union_val.val.fieldValue(fields.values()[address_space_index].ty, mod, address_space_index);
+            const child_val = try union_val.val.fieldValue(fields.values()[child_index].ty, mod, child_index);
+            const is_allowzero_val = try union_val.val.fieldValue(fields.values()[is_allowzero_index].ty, mod, is_allowzero_index);
+            const sentinel_val = try union_val.val.fieldValue(fields.values()[sentinel_index].ty, mod, sentinel_index);
 
             if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
                 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
@@ -18954,14 +18967,14 @@ fn zirReify(
             return sema.addType(ty);
         },
         .Array => {
-            const struct_val = union_val.val.castTag(.aggregate).?.data;
-            // TODO use reflection instead of magic numbers here
-            // len: comptime_int,
-            const len_val = struct_val[0];
-            // child: type,
-            const child_val = struct_val[1];
-            // sentinel: ?*const anyopaque,
-            const sentinel_val = struct_val[2];
+            const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
+            const len_index = fields.getIndex("len").?;
+            const child_index = fields.getIndex("child").?;
+            const sentinel_index = fields.getIndex("sentinel").?;
+
+            const len_val = try union_val.val.fieldValue(fields.values()[len_index].ty, mod, len_index);
+            const child_val = try union_val.val.fieldValue(fields.values()[child_index].ty, mod, child_index);
+            const sentinel_val = try union_val.val.fieldValue(fields.values()[sentinel_index].ty, mod, sentinel_index);
 
             const len = len_val.toUnsignedInt(mod);
             const child_ty = child_val.toType();
@@ -18977,10 +18990,10 @@ fn zirReify(
             return sema.addType(ty);
         },
         .Optional => {
-            const struct_val = union_val.val.castTag(.aggregate).?.data;
-            // TODO use reflection instead of magic numbers here
-            // child: type,
-            const child_val = struct_val[0];
+            const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
+            const child_index = fields.getIndex("child").?;
+
+            const child_val = try union_val.val.fieldValue(fields.values()[child_index].ty, mod, child_index);
 
             const child_ty = child_val.toType();
 
@@ -18988,12 +19001,12 @@ fn zirReify(
             return sema.addType(ty);
         },
         .ErrorUnion => {
-            const struct_val = union_val.val.castTag(.aggregate).?.data;
-            // TODO use reflection instead of magic numbers here
-            // error_set: type,
-            const error_set_val = struct_val[0];
-            // payload: type,
-            const payload_val = struct_val[1];
+            const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
+            const error_set_index = fields.getIndex("error_set").?;
+            const payload_index = fields.getIndex("payload").?;
+
+            const error_set_val = try union_val.val.fieldValue(fields.values()[error_set_index].ty, mod, error_set_index);
+            const payload_val = try union_val.val.fieldValue(fields.values()[payload_index].ty, mod, payload_index);
 
             const error_set_ty = error_set_val.toType();
             const payload_ty = payload_val.toType();
@@ -19031,19 +19044,18 @@ fn zirReify(
             return sema.addType(ty);
         },
         .Struct => {
-            // TODO use reflection instead of magic numbers here
-            const struct_val = union_val.val.castTag(.aggregate).?.data;
-            // layout: containerlayout,
-            const layout_val = struct_val[0];
-            // backing_int: ?type,
-            const backing_int_val = struct_val[1];
-            // fields: []const enumfield,
-            const fields_val = struct_val[2];
-            // decls: []const declaration,
-            const decls_val = struct_val[3];
-            // is_tuple: bool,
-            const is_tuple_val = struct_val[4];
-            assert(struct_val.len == 5);
+            const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
+            const layout_index = fields.getIndex("layout").?;
+            const backing_integer_index = fields.getIndex("backing_integer").?;
+            const fields_index = fields.getIndex("fields").?;
+            const decls_index = fields.getIndex("decls").?;
+            const is_tuple_index = fields.getIndex("is_tuple").?;
+
+            const layout_val = try union_val.val.fieldValue(fields.values()[layout_index].ty, mod, layout_index);
+            const backing_integer_val = try union_val.val.fieldValue(fields.values()[backing_integer_index].ty, mod, backing_integer_index);
+            const fields_val = try union_val.val.fieldValue(fields.values()[fields_index].ty, mod, fields_index);
+            const decls_val = try union_val.val.fieldValue(fields.values()[decls_index].ty, mod, decls_index);
+            const is_tuple_val = try union_val.val.fieldValue(fields.values()[is_tuple_index].ty, mod, is_tuple_index);
 
             const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
 
@@ -19052,23 +19064,23 @@ fn zirReify(
                 return sema.fail(block, src, "reified structs must have no decls", .{});
             }
 
-            if (layout != .Packed and !backing_int_val.isNull(mod)) {
+            if (layout != .Packed and !backing_integer_val.isNull(mod)) {
                 return sema.fail(block, src, "non-packed struct does not support backing integer type", .{});
             }
 
-            return try sema.reifyStruct(block, inst, src, layout, backing_int_val, fields_val, name_strategy, is_tuple_val.toBool(mod));
+            return try sema.reifyStruct(block, inst, src, layout, backing_integer_val, fields_val, name_strategy, is_tuple_val.toBool(mod));
         },
         .Enum => {
-            const struct_val: []const Value = union_val.val.castTag(.aggregate).?.data;
-            // TODO use reflection instead of magic numbers here
-            // tag_type: type,
-            const tag_type_val = struct_val[0];
-            // fields: []const EnumField,
-            const fields_val = struct_val[1];
-            // decls: []const Declaration,
-            const decls_val = struct_val[2];
-            // is_exhaustive: bool,
-            const is_exhaustive_val = struct_val[3];
+            const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
+            const tag_type_index = fields.getIndex("tag_type").?;
+            const fields_index = fields.getIndex("fields").?;
+            const decls_index = fields.getIndex("decls").?;
+            const is_exhaustive_index = fields.getIndex("is_exhaustive").?;
+
+            const tag_type_val = try union_val.val.fieldValue(fields.values()[tag_type_index].ty, mod, tag_type_index);
+            const fields_val = try union_val.val.fieldValue(fields.values()[fields_index].ty, mod, fields_index);
+            const decls_val = try union_val.val.fieldValue(fields.values()[decls_index].ty, mod, decls_index);
+            const is_exhaustive_val = try union_val.val.fieldValue(fields.values()[is_exhaustive_index].ty, mod, is_exhaustive_index);
 
             // Decls
             if (decls_val.sliceLen(mod) > 0) {
@@ -19160,9 +19172,10 @@ fn zirReify(
             return sema.analyzeDeclVal(block, src, new_decl_index);
         },
         .Opaque => {
-            const struct_val = union_val.val.castTag(.aggregate).?.data;
-            // decls: []const Declaration,
-            const decls_val = struct_val[0];
+            const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
+            const decls_index = fields.getIndex("decls").?;
+
+            const decls_val = try union_val.val.fieldValue(fields.values()[decls_index].ty, mod, decls_index);
 
             // Decls
             if (decls_val.sliceLen(mod) > 0) {
@@ -19205,16 +19218,16 @@ fn zirReify(
             return sema.analyzeDeclVal(block, src, new_decl_index);
         },
         .Union => {
-            // TODO use reflection instead of magic numbers here
-            const struct_val = union_val.val.castTag(.aggregate).?.data;
-            // layout: containerlayout,
-            const layout_val = struct_val[0];
-            // tag_type: ?type,
-            const tag_type_val = struct_val[1];
-            // fields: []const enumfield,
-            const fields_val = struct_val[2];
-            // decls: []const declaration,
-            const decls_val = struct_val[3];
+            const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
+            const layout_index = fields.getIndex("layout").?;
+            const tag_type_index = fields.getIndex("tag_type").?;
+            const fields_index = fields.getIndex("fields").?;
+            const decls_index = fields.getIndex("decls").?;
+
+            const layout_val = try union_val.val.fieldValue(fields.values()[layout_index].ty, mod, layout_index);
+            const tag_type_val = try union_val.val.fieldValue(fields.values()[tag_type_index].ty, mod, tag_type_index);
+            const fields_val = try union_val.val.fieldValue(fields.values()[fields_index].ty, mod, fields_index);
+            const decls_val = try union_val.val.fieldValue(fields.values()[decls_index].ty, mod, decls_index);
 
             // Decls
             if (decls_val.sliceLen(mod) > 0) {
@@ -19411,25 +19424,28 @@ fn zirReify(
             return sema.analyzeDeclVal(block, src, new_decl_index);
         },
         .Fn => {
-            const struct_val: []const Value = union_val.val.castTag(.aggregate).?.data;
-            // TODO use reflection instead of magic numbers here
-            // calling_convention: CallingConvention,
-            const cc = mod.toEnum(std.builtin.CallingConvention, struct_val[0]);
-            // alignment: comptime_int,
-            const alignment_val = struct_val[1];
-            // is_generic: bool,
-            const is_generic = struct_val[2].toBool(mod);
-            // is_var_args: bool,
-            const is_var_args = struct_val[3].toBool(mod);
-            // return_type: ?type,
-            const return_type_val = struct_val[4];
-            // args: []const Param,
-            const args_val = struct_val[5];
-
+            const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
+            const calling_convention_index = fields.getIndex("calling_convention").?;
+            const alignment_index = fields.getIndex("alignment").?;
+            const is_generic_index = fields.getIndex("is_generic").?;
+            const is_var_args_index = fields.getIndex("is_var_args").?;
+            const return_type_index = fields.getIndex("return_type").?;
+            const params_index = fields.getIndex("params").?;
+
+            const calling_convention_val = try union_val.val.fieldValue(fields.values()[calling_convention_index].ty, mod, calling_convention_index);
+            const alignment_val = try union_val.val.fieldValue(fields.values()[alignment_index].ty, mod, alignment_index);
+            const is_generic_val = try union_val.val.fieldValue(fields.values()[is_generic_index].ty, mod, is_generic_index);
+            const is_var_args_val = try union_val.val.fieldValue(fields.values()[is_var_args_index].ty, mod, is_var_args_index);
+            const return_type_val = try union_val.val.fieldValue(fields.values()[return_type_index].ty, mod, return_type_index);
+            const params_val = try union_val.val.fieldValue(fields.values()[params_index].ty, mod, params_index);
+
+            const is_generic = is_generic_val.toBool(mod);
             if (is_generic) {
                 return sema.fail(block, src, "Type.Fn.is_generic must be false for @Type", .{});
             }
 
+            const is_var_args = is_var_args_val.toBool(mod);
+            const cc = mod.toEnum(std.builtin.CallingConvention, calling_convention_val);
             if (is_var_args and cc != .C) {
                 return sema.fail(block, src, "varargs functions must have C calling convention", .{});
             }
@@ -19448,7 +19464,7 @@ fn zirReify(
             const return_type = return_type_val.optionalValue(mod) orelse
                 return sema.fail(block, src, "Type.Fn.return_type must be non-null for @Type", .{});
 
-            const args_slice_val = args_val.castTag(.slice).?.data;
+            const args_slice_val = params_val.castTag(.slice).?.data;
             const args_len = try sema.usizeCast(block, src, args_slice_val.len.toUnsignedInt(mod));
 
             const param_types = try sema.arena.alloc(InternPool.Index, args_len);
src/type.zig
@@ -3148,8 +3148,13 @@ pub const Type = struct {
     pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, mod: *Module) ?u32 {
         const ip = &mod.intern_pool;
         const enum_type = ip.indexToKey(ty.ip_index).enum_type;
-        assert(ip.typeOf(enum_tag.ip_index) == enum_type.tag_ty);
-        return enum_type.tagValueIndex(ip, enum_tag.ip_index);
+        const int_tag = switch (ip.indexToKey(enum_tag.ip_index)) {
+            .int => enum_tag.ip_index,
+            .enum_tag => |info| info.int,
+            else => unreachable,
+        };
+        assert(ip.typeOf(int_tag) == enum_type.tag_ty);
+        return enum_type.tagValueIndex(ip, int_tag);
     }
 
     pub fn structFields(ty: Type, mod: *Module) Module.Struct.Fields {