Commit 4fe0c583be

Andrew Kelley <andrew@ziglang.org>
2023-05-08 01:14:08
stage2: more InternPool-related fixes
1 parent 4d88f82
src/Module.zig
@@ -6716,6 +6716,7 @@ fn reportRetryableFileError(
 }
 
 pub fn markReferencedDeclsAlive(mod: *Module, val: Value) void {
+    if (val.ip_index != .none) return;
     switch (val.tag()) {
         .decl_ref_mut => return mod.markDeclIndexAlive(val.castTag(.decl_ref_mut).?.data.decl_index),
         .extern_fn => return mod.markDeclIndexAlive(val.castTag(.extern_fn).?.data.owner_decl),
src/Sema.zig
@@ -12307,8 +12307,7 @@ fn zirShl(
     if (block.wantSafety()) {
         const bit_count = scalar_ty.intInfo(mod).bits;
         if (!std.math.isPowerOfTwo(bit_count)) {
-            const bit_count_val = try mod.intValue(scalar_ty, bit_count);
-
+            const bit_count_val = try mod.intValue(scalar_rhs_ty, bit_count);
             const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: {
                 const bit_count_inst = try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, bit_count_val));
                 const lt = try block.addCmpVector(rhs, bit_count_inst, .lt);
@@ -27391,10 +27390,19 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {
     const prev_ptr = while (air_tags[ptr_inst] == .bitcast) {
         const prev_ptr = air_datas[ptr_inst].ty_op.operand;
         const prev_ptr_ty = sema.typeOf(prev_ptr);
-        const prev_ptr_child_ty = switch (prev_ptr_ty.tag()) {
-            .pointer => prev_ptr_ty.castTag(.pointer).?.data.pointee_type,
-            else => return null,
-        };
+        if (prev_ptr_ty.zigTypeTag(mod) != .Pointer) return null;
+
+        // TODO: I noticed that the behavior tests do not pass if these two
+        // checks are missing. I don't understand why the presence of inferred
+        // allocations is relevant to this function, or why it would have
+        // different behavior depending on whether the types were inferred.
+        // Something seems wrong here.
+        if (prev_ptr_ty.ip_index == .none) {
+            if (prev_ptr_ty.tag() == .inferred_alloc_mut) return null;
+            if (prev_ptr_ty.tag() == .inferred_alloc_const) return null;
+        }
+
+        const prev_ptr_child_ty = prev_ptr_ty.childType(mod);
         if (prev_ptr_child_ty.zigTypeTag(mod) == .Vector) break prev_ptr;
         ptr_inst = Air.refToIndex(prev_ptr) orelse return null;
     } else return null;
src/type.zig
@@ -2058,16 +2058,23 @@ pub const Type = struct {
         }
     }
 
-    pub fn ptrAddressSpace(self: Type, mod: *const Module) std.builtin.AddressSpace {
-        return switch (self.tag()) {
-            .pointer => self.castTag(.pointer).?.data.@"addrspace",
+    pub fn ptrAddressSpace(ty: Type, mod: *const Module) std.builtin.AddressSpace {
+        return switch (ty.ip_index) {
+            .none => switch (ty.tag()) {
+                .pointer => ty.castTag(.pointer).?.data.@"addrspace",
 
-            .optional => {
-                const child_type = self.optionalChild(mod);
-                return child_type.ptrAddressSpace(mod);
-            },
+                .optional => {
+                    const child_type = ty.optionalChild(mod);
+                    return child_type.ptrAddressSpace(mod);
+                },
 
-            else => unreachable,
+                else => unreachable,
+            },
+            else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
+                .ptr_type => |ptr_type| ptr_type.address_space,
+                .opt_type => |child| mod.intern_pool.indexToKey(child).ptr_type.address_space,
+                else => unreachable,
+            },
         };
     }
 
src/value.zig
@@ -644,15 +644,32 @@ pub const Value = struct {
 
     /// Asserts the type is an enum type.
     pub fn toEnum(val: Value, comptime E: type) E {
-        switch (val.tag()) {
-            .enum_field_index => {
-                const field_index = val.castTag(.enum_field_index).?.data;
-                return @intToEnum(E, field_index);
+        switch (val.ip_index) {
+            .calling_convention_c => {
+                if (E == std.builtin.CallingConvention) {
+                    return .C;
+                } else {
+                    unreachable;
+                }
+            },
+            .calling_convention_inline => {
+                if (E == std.builtin.CallingConvention) {
+                    return .Inline;
+                } else {
+                    unreachable;
+                }
             },
-            .the_only_possible_value => {
-                const fields = std.meta.fields(E);
-                assert(fields.len == 1);
-                return @intToEnum(E, fields[0].value);
+            .none => switch (val.tag()) {
+                .enum_field_index => {
+                    const field_index = val.castTag(.enum_field_index).?.data;
+                    return @intToEnum(E, field_index);
+                },
+                .the_only_possible_value => {
+                    const fields = std.meta.fields(E);
+                    assert(fields.len == 1);
+                    return @intToEnum(E, fields[0].value);
+                },
+                else => unreachable,
             },
             else => unreachable,
         }
@@ -2177,7 +2194,7 @@ pub const Value = struct {
         std.hash.autoHash(hasher, zig_ty_tag);
         if (val.isUndef()) return;
         // The value is runtime-known and shouldn't affect the hash.
-        if (val.tag() == .runtime_value) return;
+        if (val.isRuntimeValue()) return;
 
         switch (zig_ty_tag) {
             .Opaque => unreachable, // Cannot hash opaque types
@@ -2323,7 +2340,7 @@ pub const Value = struct {
     pub fn hashUncoerced(val: Value, ty: Type, hasher: *std.hash.Wyhash, mod: *Module) void {
         if (val.isUndef()) return;
         // The value is runtime-known and shouldn't affect the hash.
-        if (val.tag() == .runtime_value) return;
+        if (val.isRuntimeValue()) return;
 
         switch (ty.zigTypeTag(mod)) {
             .Opaque => unreachable, // Cannot hash opaque types