diff --git a/src/InternPool.zig b/src/InternPool.zig index 6264dc5ab2..35fc84ddc1 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -11913,23 +11913,29 @@ pub fn aggregateTypeLenIncludingSentinel(ip: *const InternPool, ty: Index) u64 { } pub fn funcTypeReturnType(ip: *const InternPool, ty: Index) Index { - const unwrapped_ty = ty.unwrap(ip); - const ty_extra = unwrapped_ty.getExtra(ip); - const ty_item = unwrapped_ty.getItem(ip); - const child_extra, const child_item = switch (ty_item.tag) { - .type_pointer => child: { - const child_index: Index = @enumFromInt(ty_extra.view().items(.@"0")[ - ty_item.data + std.meta.fieldIndex(Tag.TypePointer, "child").? - ]); - const unwrapped_child = child_index.unwrap(ip); - break :child .{ unwrapped_child.getExtra(ip), unwrapped_child.getItem(ip) }; - }, - .type_function => .{ ty_extra, ty_item }, - else => unreachable, + var ty_item, var ty_extra = unwrapped: { + const unwrapped_ty = ty.unwrap(ip); + break :unwrapped .{ unwrapped_ty.getItem(ip), unwrapped_ty.getExtra(ip) }; }; - assert(child_item.tag == .type_function); - return @enumFromInt(child_extra.view().items(.@"0")[ - child_item.data + std.meta.fieldIndex(Tag.TypeFunction, "return_type").? + if (ty_item.tag == .type_restricted) { + const unrestricted_ty: Index = @enumFromInt(ty_extra.view().items(.@"0")[ + ty_item.data + std.meta.fieldIndex(Tag.TypeRestricted, "unrestricted_type").? + ]); + const unwrapped_ty = unrestricted_ty.unwrap(ip); + ty_item = unwrapped_ty.getItem(ip); + ty_extra = unwrapped_ty.getExtra(ip); + } + if (ty_item.tag == .type_pointer) { + const child_ty: Index = @enumFromInt(ty_extra.view().items(.@"0")[ + ty_item.data + std.meta.fieldIndex(Tag.TypePointer, "child").? + ]); + const unwrapped_ty = child_ty.unwrap(ip); + ty_item = unwrapped_ty.getItem(ip); + ty_extra = unwrapped_ty.getExtra(ip); + } + assert(ty_item.tag == .type_function); + return @enumFromInt(ty_extra.view().items(.@"0")[ + ty_item.data + std.meta.fieldIndex(Tag.TypeFunction, "return_type").? ]); } diff --git a/src/Sema.zig b/src/Sema.zig index d7d0b517a6..21d2b5de19 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -6274,16 +6274,17 @@ fn checkCallArgumentCount( const pt = sema.pt; const zcu = pt.zcu; const func_ty: Type = func_ty: { - switch (callee_ty.zigTypeTag(zcu)) { - .@"fn" => break :func_ty callee_ty, + const unrestricted_callee_ty = callee_ty.unrestrictedType(zcu) orelse callee_ty; + switch (unrestricted_callee_ty.zigTypeTag(zcu)) { + .@"fn" => break :func_ty unrestricted_callee_ty, .pointer => { - const ptr_info = callee_ty.ptrInfo(zcu); + const ptr_info = unrestricted_callee_ty.ptrInfo(zcu); if (ptr_info.flags.size == .one and Type.fromInterned(ptr_info.child).zigTypeTag(zcu) == .@"fn") { break :func_ty .fromInterned(ptr_info.child); } }, .optional => { - const opt_child = callee_ty.optionalChild(zcu); + const opt_child = unrestricted_callee_ty.optionalChild(zcu); if (opt_child.zigTypeTag(zcu) == .@"fn" or (opt_child.isSinglePointer(zcu) and opt_child.childType(zcu).zigTypeTag(zcu) == .@"fn")) { @@ -7012,13 +7013,21 @@ fn analyzeCall( break :func .{ Air.internedToRef(func_instance), runtime_args.items }; }; - ref_func: { - const runtime_func_val = sema.resolveValue(runtime_func) orelse break :ref_func; - if (!ip.isFuncBody(runtime_func_val.toIntern())) break :ref_func; - const orig_fn_index = ip.unwrapCoercedFunc(runtime_func_val.toIntern()); - try sema.addReferenceEntry(block, call_src, .wrap(.{ .func = orig_fn_index })); - try zcu.ensureFuncBodyAnalysisQueued(orig_fn_index); - } + const unrestricted_runtime_func: Air.Inst.Ref = if (sema.resolveValue(runtime_func)) |runtime_func_val| unrestricted_runtime_func: { + const unrestricted_runtime_func_val = switch (ip.indexToKey(runtime_func_val.toIntern())) { + else => runtime_func_val.toIntern(), + .restricted_value => |restricted_value| restricted_value.unrestricted_value, + }; + if (ip.isFuncBody(unrestricted_runtime_func_val)) { + const orig_fn_index = ip.unwrapCoercedFunc(unrestricted_runtime_func_val); + try sema.addReferenceEntry(block, call_src, .wrap(.{ .func = orig_fn_index })); + try zcu.ensureFuncBodyAnalysisQueued(orig_fn_index); + } + break :unrestricted_runtime_func .fromIntern(unrestricted_runtime_func_val); + } else if (sema.typeOf(runtime_func).unrestrictedType(zcu)) |unrestricted_ty| + try sema.unwrapRestricted(block, unrestricted_ty, runtime_func, func_src) + else + runtime_func; const call_tag: Air.Inst.Tag = switch (modifier) { .auto, .no_suspend => .call, @@ -7035,7 +7044,7 @@ fn analyzeCall( const call_ref = try block.addInst(.{ .tag = call_tag, .data = .{ .pl_op = .{ - .operand = runtime_func, + .operand = unrestricted_runtime_func, .payload = sema.addExtraAssumeCapacity(Air.Call{ .args_len = @intCast(runtime_args.len), }), @@ -7050,10 +7059,10 @@ fn analyzeCall( } if (call_tag == .call_always_tail) { - const func_or_ptr_ty = sema.typeOf(runtime_func); - const runtime_func_ty = switch (func_or_ptr_ty.zigTypeTag(zcu)) { - .@"fn" => func_or_ptr_ty, - .pointer => func_or_ptr_ty.childType(zcu), + const unrestricted_runtime_func_ty = sema.typeOf(unrestricted_runtime_func); + const runtime_func_ty = switch (unrestricted_runtime_func_ty.zigTypeTag(zcu)) { + .@"fn" => unrestricted_runtime_func_ty, + .pointer => unrestricted_runtime_func_ty.childType(zcu), else => unreachable, }; const result = sema.coerceExtra(block, sema.fn_ret_ty, call_ref, call_src, .{ .is_ret = true }) catch |err| switch (err) { @@ -9129,11 +9138,8 @@ fn analyzeAs( const zcu = pt.zcu; const operand = sema.resolveInst(zir_operand); const dest_ty = try sema.resolveTypeOrPoison(block, src, zir_dest_type) orelse return operand; - switch (dest_ty.zigTypeTag(zcu)) { - .@"opaque" => return sema.fail(block, src, "cannot cast to opaque type '{f}'", .{dest_ty.fmt(pt)}), - .noreturn => return sema.fail(block, src, "cannot cast to noreturn", .{}), - else => {}, - } + if (dest_ty.toIntern() == .noreturn_type) return sema.fail(block, src, "cannot cast to noreturn", .{}); + if (zcu.intern_pool.isOpaqueType(dest_ty.toIntern())) return sema.fail(block, src, "cannot cast to opaque type '{f}'", .{dest_ty.fmt(pt)}); const is_ret = if (zir_dest_type.toIndex()) |ptr_index| sema.code.instructions.items(.tag)[@intFromEnum(ptr_index)] == .ret_type diff --git a/src/Sema/type_resolution.zig b/src/Sema/type_resolution.zig index f975f04782..37d4474e9c 100644 --- a/src/Sema/type_resolution.zig +++ b/src/Sema/type_resolution.zig @@ -289,7 +289,7 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void { assert(!field_ty.isGenericPoison()); const field_ty_src = block.src(.{ .container_field_type = @intCast(field_index) }); try sema.ensureLayoutResolved(field_ty, field_ty_src, .field); - if (field_ty.zigTypeTag(zcu) == .@"opaque") { + if (ip.isOpaqueType(field_ty.toIntern())) { return sema.failWithOwnedErrorMsg(&block, msg: { const msg = try sema.errMsg(field_ty_src, "cannot directly embed opaque type '{f}' in struct", .{field_ty.fmt(pt)}); errdefer msg.destroy(gpa);