diff --git a/src/Sema.zig b/src/Sema.zig index 342213dad18e2035dbcb4a9c53312762ac4f3b38..81447d6361b23f947907881648e7412ac0de21d9 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -17030,14 +17030,14 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in const payload_val = union_val.val.optionalValue() orelse return sema.addType(Type.initTag(.anyerror)); const slice_val = payload_val.castTag(.slice).?.data; - const decl_index = slice_val.ptr.pointerDecl().?; - try sema.ensureDeclAnalyzed(decl_index); - const decl = mod.declPtr(decl_index); - const array_val: []Value = if (decl.val.castTag(.aggregate)) |some| some.data else &.{}; + const len = try sema.usizeCast(block, src, slice_val.len.toUnsignedInt(mod.getTarget())); var names: Module.ErrorSet.NameMap = .{}; - try names.ensureUnusedCapacity(sema.arena, array_val.len); - for (array_val) |elem_val| { + try names.ensureUnusedCapacity(sema.arena, len); + var i: usize = 0; + while (i < len) : (i += 1) { + var buf: Value.ElemValueBuffer = undefined; + const elem_val = slice_val.ptr.elemValueBuffer(mod, i, &buf); const struct_val = elem_val.castTag(.aggregate).?.data; // TODO use reflection instead of magic numbers here // error_set: type, @@ -17429,14 +17429,14 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in var buf: Value.ToTypeBuffer = undefined; const args_slice_val = args_val.castTag(.slice).?.data; - const args_decl_index = args_slice_val.ptr.pointerDecl().?; - try sema.ensureDeclAnalyzed(args_decl_index); - const args_decl = mod.declPtr(args_decl_index); - const args: []Value = if (args_decl.val.castTag(.aggregate)) |some| some.data else &.{}; - var param_types = try sema.arena.alloc(Type, args.len); - var comptime_params = try sema.arena.alloc(bool, args.len); + const args_len = try sema.usizeCast(block, src, args_slice_val.len.toUnsignedInt(mod.getTarget())); + var param_types = try sema.arena.alloc(Type, args_len); + var comptime_params = try sema.arena.alloc(bool, args_len); var noalias_bits: u32 = 0; - for (args) |arg, i| { + var i: usize = 0; + while (i < args_len) : (i += 1) { + var arg_buf: Value.ElemValueBuffer = undefined; + const arg = args_slice_val.ptr.elemValueBuffer(mod, i, &arg_buf); const arg_val = arg.castTag(.aggregate).?.data; // TODO use reflection instead of magic numbers here // is_generic: bool, diff --git a/test/behavior.zig b/test/behavior.zig index febd765d779c7da71f6d7c7198265090c9207d72..a4acb57124b9266cfb0a8d1a078c8c9465dc5f43 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -93,6 +93,7 @@ test { _ = @import("behavior/bugs/12794.zig"); _ = @import("behavior/bugs/12801-1.zig"); _ = @import("behavior/bugs/12801-2.zig"); + _ = @import("behavior/bugs/12885.zig"); _ = @import("behavior/bugs/12911.zig"); _ = @import("behavior/bugs/12928.zig"); _ = @import("behavior/byteswap.zig"); diff --git a/test/behavior/bugs/12885.zig b/test/behavior/bugs/12885.zig new file mode 100644 index 0000000000000000000000000000000000000000..f1cc8f94b3e18f9c9e347696d03473f3746fe353 --- /dev/null +++ b/test/behavior/bugs/12885.zig @@ -0,0 +1,36 @@ +const std = @import("std"); +const builtin = std.builtin; +const expect = std.testing.expect; + +const info = .{ + .args = [_]builtin.Type.Error{ + .{ .name = "bar" }, + }, +}; +const Foo = @Type(.{ + .ErrorSet = &info.args, +}); +test "ErrorSet comptime_field_ptr" { + if (@import("builtin").zig_backend == .stage1) return error.SkipZigTest; + + try expect(Foo == error{bar}); +} + +const fn_info = .{ + .args = [_]builtin.Type.Fn.Param{ + .{ .is_generic = false, .is_noalias = false, .arg_type = u8 }, + }, +}; +const Bar = @Type(.{ + .Fn = .{ + .calling_convention = .Unspecified, + .alignment = 0, + .is_generic = false, + .is_var_args = false, + .return_type = void, + .args = &fn_info.args, + }, +}); +test "fn comptime_field_ptr" { + try expect(@typeInfo(Bar) == .Fn); +}