diff --git a/src/InternPool.zig b/src/InternPool.zig index d4bfe5a244..bf48aeda84 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -132,6 +132,9 @@ pub const Key = union(enum) { array_type: ArrayType, vector_type: VectorType, opt_type: Index, + /// `anyframe->T`. The payload is the child type, which may be `none` to indicate + /// `anyframe`. + anyframe_type: Index, error_union_type: struct { error_set_type: Index, payload_type: Index, @@ -503,6 +506,7 @@ pub const Key = union(enum) { .array_type, .vector_type, .opt_type, + .anyframe_type, .error_union_type, .simple_type, .simple_value, @@ -597,7 +601,11 @@ pub const Key = union(enum) { }, .opt_type => |a_info| { const b_info = b.opt_type; - return std.meta.eql(a_info, b_info); + return a_info == b_info; + }, + .anyframe_type => |a_info| { + const b_info = b.anyframe_type; + return a_info == b_info; }, .error_union_type => |a_info| { const b_info = b.error_union_type; @@ -752,6 +760,7 @@ pub const Key = union(enum) { .array_type, .vector_type, .opt_type, + .anyframe_type, .error_union_type, .simple_type, .struct_type, @@ -1037,7 +1046,7 @@ pub const static_keys = [_]Key{ .{ .simple_type = .comptime_int }, .{ .simple_type = .comptime_float }, .{ .simple_type = .noreturn }, - .{ .simple_type = .@"anyframe" }, + .{ .anyframe_type = .none }, .{ .simple_type = .null }, .{ .simple_type = .undefined }, .{ .simple_type = .enum_literal }, @@ -1203,6 +1212,10 @@ pub const Tag = enum(u8) { /// An optional type. /// data is the child type. type_optional, + /// The type `anyframe->T`. + /// data is the child type. + /// If the child type is `none`, the type is `anyframe`. + type_anyframe, /// An error union type. /// data is payload to ErrorUnion. type_error_union, @@ -1421,7 +1434,6 @@ pub const SimpleType = enum(u32) { comptime_int, comptime_float, noreturn, - @"anyframe", null, undefined, enum_literal, @@ -1781,6 +1793,7 @@ pub fn indexToKey(ip: InternPool, index: Index) Key { }, .type_optional => .{ .opt_type = @intToEnum(Index, data) }, + .type_anyframe => .{ .anyframe_type = @intToEnum(Index, data) }, .type_error_union => @panic("TODO"), @@ -2144,10 +2157,18 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { }), }); }, - .opt_type => |opt_type| { + .opt_type => |payload_type| { + assert(payload_type != .none); ip.items.appendAssumeCapacity(.{ .tag = .type_optional, - .data = @enumToInt(opt_type), + .data = @enumToInt(payload_type), + }); + }, + .anyframe_type => |payload_type| { + // payload_type might be none, indicating the type is `anyframe`. + ip.items.appendAssumeCapacity(.{ + .tag = .type_anyframe, + .data = @enumToInt(payload_type), }); }, .error_union_type => |error_union_type| { @@ -3063,7 +3084,7 @@ pub fn childType(ip: InternPool, i: Index) Index { .ptr_type => |ptr_type| ptr_type.elem_type, .vector_type => |vector_type| vector_type.child, .array_type => |array_type| array_type.child, - .opt_type => |child| child, + .opt_type, .anyframe_type => |child| child, else => unreachable, }; } @@ -3231,6 +3252,7 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void { .type_pointer => @sizeOf(Pointer), .type_slice => 0, .type_optional => 0, + .type_anyframe => 0, .type_error_union => @sizeOf(ErrorUnion), .type_enum_explicit, .type_enum_nonexhaustive => @sizeOf(EnumExplicit), .type_enum_auto => @sizeOf(EnumAuto), diff --git a/src/Module.zig b/src/Module.zig index c8e676f813..0a063a8ddc 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -6869,6 +6869,12 @@ pub fn funcType(mod: *Module, info: InternPool.Key.FuncType) Allocator.Error!Typ return (try intern(mod, .{ .func_type = info })).toType(); } +/// Use this for `anyframe->T` only. +/// For `anyframe`, use the `InternPool.Index.anyframe` tag directly. +pub fn anyframeType(mod: *Module, payload_ty: Type) Allocator.Error!Type { + return (try intern(mod, .{ .anyframe_type = payload_ty.toIntern() })).toType(); +} + /// Supports optionals in addition to pointers. pub fn ptrIntValue(mod: *Module, ty: Type, x: u64) Allocator.Error!Value { if (ty.isPtrLikeOptional(mod)) { diff --git a/src/Sema.zig b/src/Sema.zig index eb8dc5a633..c855c5e188 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -8042,9 +8042,10 @@ fn zirAnyframeType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro if (true) { return sema.failWithUseOfAsync(block, inst_data.src()); } + const mod = sema.mod; const operand_src: LazySrcLoc = .{ .node_offset_anyframe_type = inst_data.src_node }; const return_type = try sema.resolveType(block, operand_src, inst_data.operand); - const anyframe_type = try Type.Tag.anyframe_T.create(sema.arena, return_type); + const anyframe_type = try mod.anyframeType(return_type); return sema.addType(anyframe_type); } @@ -31626,10 +31627,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { }, .error_union => return sema.resolveTypeRequiresComptime(ty.errorUnionPayload()), - .anyframe_T => { - const child_ty = ty.castTag(.anyframe_T).?.data; - return sema.resolveTypeRequiresComptime(child_ty); - }, }, else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { .int_type => false, @@ -31641,6 +31638,10 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { return sema.resolveTypeRequiresComptime(child_ty); } }, + .anyframe_type => |child| { + if (child == .none) return false; + return sema.resolveTypeRequiresComptime(child.toType()); + }, .array_type => |array_type| return sema.resolveTypeRequiresComptime(array_type.child.toType()), .vector_type => |vector_type| return sema.resolveTypeRequiresComptime(vector_type.child.toType()), .opt_type => |child| return sema.resolveTypeRequiresComptime(child.toType()), @@ -31669,7 +31670,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { .bool, .void, .anyerror, - .@"anyframe", .noreturn, .generic_poison, .var_args_param, @@ -33054,7 +33054,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { .error_set_merged, .error_union, .error_set_inferred, - .anyframe_T, .pointer, => return null, @@ -33083,6 +33082,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { .ptr_type, .error_union_type, .func_type, + .anyframe_type, => null, .array_type => |array_type| { @@ -33130,7 +33130,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { .anyerror, .comptime_int, .comptime_float, - .@"anyframe", .enum_literal, .atomic_order, .atomic_rmw_op, @@ -33688,10 +33687,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { }, .error_union => return sema.typeRequiresComptime(ty.errorUnionPayload()), - .anyframe_T => { - const child_ty = ty.castTag(.anyframe_T).?.data; - return sema.typeRequiresComptime(child_ty); - }, }, else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { .int_type => return false, @@ -33703,6 +33698,10 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { return sema.typeRequiresComptime(child_ty); } }, + .anyframe_type => |child| { + if (child == .none) return false; + return sema.typeRequiresComptime(child.toType()); + }, .array_type => |array_type| return sema.typeRequiresComptime(array_type.child.toType()), .vector_type => |vector_type| return sema.typeRequiresComptime(vector_type.child.toType()), .opt_type => |child| return sema.typeRequiresComptime(child.toType()), @@ -33733,7 +33732,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { .bool, .void, .anyerror, - .@"anyframe", .noreturn, .generic_poison, .atomic_order, diff --git a/src/type.zig b/src/type.zig index daf8b305cc..6986f2fc07 100644 --- a/src/type.zig +++ b/src/type.zig @@ -50,21 +50,20 @@ pub const Type = struct { .optional => return .Optional, .error_union => return .ErrorUnion, - - .anyframe_T => return .AnyFrame, }, - else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { - .int_type => return .Int, - .ptr_type => return .Pointer, - .array_type => return .Array, - .vector_type => return .Vector, - .opt_type => return .Optional, - .error_union_type => return .ErrorUnion, - .struct_type, .anon_struct_type => return .Struct, - .union_type => return .Union, - .opaque_type => return .Opaque, - .enum_type => return .Enum, - .func_type => return .Fn, + else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) { + .int_type => .Int, + .ptr_type => .Pointer, + .array_type => .Array, + .vector_type => .Vector, + .opt_type => .Optional, + .error_union_type => .ErrorUnion, + .struct_type, .anon_struct_type => .Struct, + .union_type => .Union, + .opaque_type => .Opaque, + .enum_type => .Enum, + .func_type => .Fn, + .anyframe_type => .AnyFrame, .simple_type => |s| switch (s) { .f16, .f32, @@ -72,7 +71,7 @@ pub const Type = struct { .f80, .f128, .c_longdouble, - => return .Float, + => .Float, .usize, .isize, @@ -85,20 +84,19 @@ pub const Type = struct { .c_ulong, .c_longlong, .c_ulonglong, - => return .Int, + => .Int, - .anyopaque => return .Opaque, - .bool => return .Bool, - .void => return .Void, - .type => return .Type, - .anyerror => return .ErrorSet, - .comptime_int => return .ComptimeInt, - .comptime_float => return .ComptimeFloat, - .noreturn => return .NoReturn, - .@"anyframe" => return .AnyFrame, - .null => return .Null, - .undefined => return .Undefined, - .enum_literal => return .EnumLiteral, + .anyopaque => .Opaque, + .bool => .Bool, + .void => .Void, + .type => .Type, + .anyerror => .ErrorSet, + .comptime_int => .ComptimeInt, + .comptime_float => .ComptimeFloat, + .noreturn => .NoReturn, + .null => .Null, + .undefined => .Undefined, + .enum_literal => .EnumLiteral, .atomic_order, .atomic_rmw_op, @@ -107,14 +105,14 @@ pub const Type = struct { .float_mode, .reduce_op, .call_modifier, - => return .Enum, + => .Enum, .prefetch_options, .export_options, .extern_options, - => return .Struct, + => .Struct, - .type_info => return .Union, + .type_info => .Union, .generic_poison => return error.GenericPoison, .var_args_param => unreachable, @@ -408,11 +406,6 @@ pub const Type = struct { return true; }, - - .anyframe_T => { - if (b.zigTypeTag(mod) != .AnyFrame) return false; - return a.elemType2(mod).eql(b.elemType2(mod), mod); - }, } } @@ -488,11 +481,6 @@ pub const Type = struct { const payload_ty = ty.errorUnionPayload(); hashWithHasher(payload_ty, hasher, mod); }, - - .anyframe_T => { - std.hash.autoHash(hasher, std.builtin.TypeId.AnyFrame); - hashWithHasher(ty.childType(mod), hasher, mod); - }, } } @@ -542,9 +530,7 @@ pub const Type = struct { .inferred_alloc_mut, => unreachable, - .optional, - .anyframe_T, - => { + .optional => { const payload = self.cast(Payload.ElemType).?; const new_payload = try allocator.create(Payload.ElemType); new_payload.* = .{ @@ -668,12 +654,6 @@ pub const Type = struct { while (true) { const t = ty.tag(); switch (t) { - .anyframe_T => { - const return_type = ty.castTag(.anyframe_T).?.data; - try writer.print("anyframe->", .{}); - ty = return_type; - continue; - }, .optional => { const child_type = ty.castTag(.optional).?.data; try writer.writeByte('?'); @@ -838,11 +818,6 @@ pub const Type = struct { try writer.writeByte('?'); try print(child_type, writer, mod); }, - .anyframe_T => { - const return_type = ty.castTag(.anyframe_T).?.data; - try writer.print("anyframe->", .{}); - try print(return_type, writer, mod); - }, .error_set => { const names = ty.castTag(.error_set).?.data.names.keys(); try writer.writeAll("error{"); @@ -1034,6 +1009,11 @@ pub const Type = struct { try print(fn_info.return_type.toType(), writer, mod); } }, + .anyframe_type => |child| { + if (child == .none) return writer.writeAll("anyframe"); + try writer.writeAll("anyframe->"); + return print(child.toType(), writer, mod); + }, // values, not types .undef => unreachable, @@ -1098,9 +1078,7 @@ pub const Type = struct { // Pointers to zero-bit types still have a runtime address; however, pointers // to comptime-only types do not, with the exception of function pointers. - .anyframe_T, - .pointer, - => { + .pointer => { if (ignore_comptime_only) { return true; } else if (ty.childType(mod).zigTypeTag(mod) == .Fn) { @@ -1141,6 +1119,7 @@ pub const Type = struct { if (strat == .sema) return !(try strat.sema.typeRequiresComptime(ty)); return !comptimeOnly(ty, mod); }, + .anyframe_type => true, .array_type => |array_type| { if (array_type.sentinel != .none) { return array_type.child.toType().hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat); @@ -1195,7 +1174,6 @@ pub const Type = struct { .c_longdouble, .bool, .anyerror, - .@"anyframe", .anyopaque, .atomic_order, .atomic_rmw_op, @@ -1319,7 +1297,6 @@ pub const Type = struct { .error_set_inferred, .error_set_merged, .error_union, - .anyframe_T, => false, .inferred_alloc_mut => unreachable, @@ -1336,6 +1313,7 @@ pub const Type = struct { .error_union_type, .anon_struct_type, .opaque_type, + .anyframe_type, // These are function bodies, not function pointers. .func_type, => false, @@ -1366,7 +1344,6 @@ pub const Type = struct { => true, .anyerror, - .@"anyframe", .anyopaque, .atomic_order, .atomic_rmw_op, @@ -1594,9 +1571,7 @@ pub const Type = struct { switch (ty.ip_index) { .empty_struct_type => return AbiAlignmentAdvanced{ .scalar = 0 }, .none => switch (ty.tag()) { - .pointer, - .anyframe_T, - => return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) }, + .pointer => return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) }, // TODO revisit this when we have the concept of the error tag type .error_set_inferred, @@ -1617,7 +1592,7 @@ pub const Type = struct { if (int_type.bits == 0) return AbiAlignmentAdvanced{ .scalar = 0 }; return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(int_type.bits, target) }; }, - .ptr_type => { + .ptr_type, .anyframe_type => { return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) }; }, .array_type => |array_type| { @@ -1657,7 +1632,6 @@ pub const Type = struct { .isize, .export_options, .extern_options, - .@"anyframe", => return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) }, .c_char => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.char) }, @@ -1976,8 +1950,6 @@ pub const Type = struct { .inferred_alloc_const => unreachable, .inferred_alloc_mut => unreachable, - .anyframe_T => return AbiSizeAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) }, - .pointer => switch (ty.castTag(.pointer).?.data.size) { .Slice => return AbiSizeAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) * 2 }, else => return AbiSizeAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) }, @@ -2039,6 +2011,8 @@ pub const Type = struct { .Slice => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) * 2 }, else => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) }, }, + .anyframe_type => return AbiSizeAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) }, + .array_type => |array_type| { const len = array_type.len + @boolToInt(array_type.sentinel != .none); switch (try array_type.child.toType().abiSizeAdvanced(mod, strat)) { @@ -2102,7 +2076,6 @@ pub const Type = struct { .usize, .isize, - .@"anyframe", => return AbiSizeAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) }, .c_char => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.char) }, @@ -2298,8 +2271,6 @@ pub const Type = struct { .inferred_alloc_const => unreachable, .inferred_alloc_mut => unreachable, - .anyframe_T => return target.ptrBitWidth(), - .pointer => switch (ty.castTag(.pointer).?.data.size) { .Slice => return target.ptrBitWidth() * 2, else => return target.ptrBitWidth(), @@ -2323,6 +2294,8 @@ pub const Type = struct { .Slice => return target.ptrBitWidth() * 2, else => return target.ptrBitWidth() * 2, }, + .anyframe_type => return target.ptrBitWidth(), + .array_type => |array_type| { const len = array_type.len + @boolToInt(array_type.sentinel != .none); if (len == 0) return 0; @@ -2349,7 +2322,6 @@ pub const Type = struct { .usize, .isize, - .@"anyframe", => return target.ptrBitWidth(), .c_char => return target.c_type_bit_size(.char), @@ -2777,8 +2749,6 @@ pub const Type = struct { }, .optional => ty.castTag(.optional).?.data.childType(mod), - .anyframe_T => ty.castTag(.anyframe_T).?.data, - else => unreachable, }, else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { @@ -2786,6 +2756,10 @@ pub const Type = struct { .One => ptr_type.elem_type.toType().shallowElemType(mod), .Many, .C, .Slice => ptr_type.elem_type.toType(), }, + .anyframe_type => |child| { + assert(child != .none); + return child.toType(); + }, .vector_type => |vector_type| vector_type.child.toType(), .array_type => |array_type| array_type.child.toType(), .opt_type => |child| mod.intern_pool.childType(child).toType(), @@ -3154,6 +3128,7 @@ pub const Type = struct { .anon_struct_type => unreachable, .ptr_type => unreachable, + .anyframe_type => unreachable, .array_type => unreachable, .opt_type => unreachable, @@ -3327,7 +3302,6 @@ pub const Type = struct { .error_set, .error_set_merged, .error_set_inferred, - .anyframe_T, .pointer, => return null, @@ -3355,6 +3329,7 @@ pub const Type = struct { .ptr_type, .error_union_type, .func_type, + .anyframe_type, => return null, .array_type => |array_type| { @@ -3401,7 +3376,6 @@ pub const Type = struct { .anyerror, .comptime_int, .comptime_float, - .@"anyframe", .enum_literal, .atomic_order, .atomic_rmw_op, @@ -3555,10 +3529,6 @@ pub const Type = struct { }, .error_union => return ty.errorUnionPayload().comptimeOnly(mod), - .anyframe_T => { - const child_ty = ty.castTag(.anyframe_T).?.data; - return child_ty.comptimeOnly(mod); - }, }, else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { .int_type => false, @@ -3570,6 +3540,10 @@ pub const Type = struct { return child_ty.comptimeOnly(mod); } }, + .anyframe_type => |child| { + if (child == .none) return false; + return child.toType().comptimeOnly(mod); + }, .array_type => |array_type| array_type.child.toType().comptimeOnly(mod), .vector_type => |vector_type| vector_type.child.toType().comptimeOnly(mod), .opt_type => |child| child.toType().comptimeOnly(mod), @@ -3599,7 +3573,6 @@ pub const Type = struct { .bool, .void, .anyerror, - .@"anyframe", .noreturn, .generic_poison, .atomic_order, @@ -4245,7 +4218,6 @@ pub const Type = struct { pointer, optional, error_union, - anyframe_T, error_set, error_set_single, /// The type is the inferred error set of a specific function. @@ -4261,9 +4233,7 @@ pub const Type = struct { .inferred_alloc_mut, => @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"), - .optional, - .anyframe_T, - => Payload.ElemType, + .optional => Payload.ElemType, .error_set => Payload.ErrorSet, .error_set_inferred => Payload.ErrorSetInferred,