diff --git a/src/Module.zig b/src/Module.zig index ef38e6ff06..d06d22402a 100644 --- a/src/Module.zig +++ b/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), diff --git a/src/Sema.zig b/src/Sema.zig index 8725704937..b8b0a6513f 100644 --- a/src/Sema.zig +++ b/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; diff --git a/src/type.zig b/src/type.zig index 9c8c1f1591..b271a3ea45 100644 --- a/src/type.zig +++ b/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 => 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, }, - - else => unreachable, }; } diff --git a/src/value.zig b/src/value.zig index 402e0981d3..d771f53a3e 100644 --- a/src/value.zig +++ b/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; + } }, - .the_only_possible_value => { - const fields = std.meta.fields(E); - assert(fields.len == 1); - return @intToEnum(E, fields[0].value); + .calling_convention_inline => { + if (E == std.builtin.CallingConvention) { + return .Inline; + } else { + unreachable; + } + }, + .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