authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-07-13 00:40:16-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-07-18 19:02:06-07:00
log927f6ec8ca2234e8c4f27174359d5053da63a77d
tree7e09d07b142f12e5ae4ff94ff48fa7e63ba96f87
parent82db06fa673dabc640c4c954df0dee7a8a6d3bfc

frontend: fix inferred error sets of comptime/inline calls

Previously, they shared function index with the owner decl, but that would clobber the data stored for inferred error sets of runtime calls. Now there is an adhoc_inferred_error_set_type which models the problem much more correctly.

5 files changed, 151 insertions(+), 50 deletions(-)

src/Air.zig+1
...@@ -946,6 +946,7 @@ pub const Inst = struct {...@@ -946,6 +946,7 @@ pub const Inst = struct {
946 slice_const_u8_sentinel_0_type = @intFromEnum(InternPool.Index.slice_const_u8_sentinel_0_type),946 slice_const_u8_sentinel_0_type = @intFromEnum(InternPool.Index.slice_const_u8_sentinel_0_type),
947 optional_noreturn_type = @intFromEnum(InternPool.Index.optional_noreturn_type),947 optional_noreturn_type = @intFromEnum(InternPool.Index.optional_noreturn_type),
948 anyerror_void_error_union_type = @intFromEnum(InternPool.Index.anyerror_void_error_union_type),948 anyerror_void_error_union_type = @intFromEnum(InternPool.Index.anyerror_void_error_union_type),
949 adhoc_inferred_error_set_type = @intFromEnum(InternPool.Index.adhoc_inferred_error_set_type),
949 generic_poison_type = @intFromEnum(InternPool.Index.generic_poison_type),950 generic_poison_type = @intFromEnum(InternPool.Index.generic_poison_type),
950 empty_struct_type = @intFromEnum(InternPool.Index.empty_struct_type),951 empty_struct_type = @intFromEnum(InternPool.Index.empty_struct_type),
951 undef = @intFromEnum(InternPool.Index.undef),952 undef = @intFromEnum(InternPool.Index.undef),
src/InternPool.zig+14-5
...@@ -1450,6 +1450,8 @@ pub const Index = enum(u32) {...@@ -1450,6 +1450,8 @@ pub const Index = enum(u32) {
1450 slice_const_u8_sentinel_0_type,1450 slice_const_u8_sentinel_0_type,
1451 optional_noreturn_type,1451 optional_noreturn_type,
1452 anyerror_void_error_union_type,1452 anyerror_void_error_union_type,
1453 /// Used for the inferred error set of inline/comptime function calls.
1454 adhoc_inferred_error_set_type,
1453 generic_poison_type,1455 generic_poison_type,
1454 /// `@TypeOf(.{})`1456 /// `@TypeOf(.{})`
1455 empty_struct_type,1457 empty_struct_type,
...@@ -1886,6 +1888,8 @@ pub const static_keys = [_]Key{...@@ -1886,6 +1888,8 @@ pub const static_keys = [_]Key{
1886 .payload_type = .void_type,1888 .payload_type = .void_type,
1887 } },1889 } },
18881890
1891 // adhoc_inferred_error_set_type
1892 .{ .simple_type = .adhoc_inferred_error_set },
1889 // generic_poison_type1893 // generic_poison_type
1890 .{ .simple_type = .generic_poison },1894 .{ .simple_type = .generic_poison },
18911895
...@@ -2496,6 +2500,7 @@ pub const SimpleType = enum(u32) {...@@ -2496,6 +2500,7 @@ pub const SimpleType = enum(u32) {
2496 extern_options,2500 extern_options,
2497 type_info,2501 type_info,
24982502
2503 adhoc_inferred_error_set,
2499 generic_poison,2504 generic_poison,
2500};2505};
25012506
...@@ -5812,14 +5817,17 @@ pub fn isOptionalType(ip: *const InternPool, ty: Index) bool {...@@ -5812,14 +5817,17 @@ pub fn isOptionalType(ip: *const InternPool, ty: Index) bool {
58125817
5813/// includes .inferred_error_set_type5818/// includes .inferred_error_set_type
5814pub fn isErrorSetType(ip: *const InternPool, ty: Index) bool {5819pub fn isErrorSetType(ip: *const InternPool, ty: Index) bool {
5815 return ty == .anyerror_type or switch (ip.indexToKey(ty)) {5820 return switch (ty) {
5816 .error_set_type, .inferred_error_set_type => true,5821 .anyerror_type, .adhoc_inferred_error_set_type => true,
5817 else => false,5822 else => switch (ip.indexToKey(ty)) {
5823 .error_set_type, .inferred_error_set_type => true,
5824 else => false,
5825 },
5818 };5826 };
5819}5827}
58205828
5821pub fn isInferredErrorSetType(ip: *const InternPool, ty: Index) bool {5829pub fn isInferredErrorSetType(ip: *const InternPool, ty: Index) bool {
5822 return ip.indexToKey(ty) == .inferred_error_set_type;5830 return ty == .adhoc_inferred_error_set_type or ip.indexToKey(ty) == .inferred_error_set_type;
5823}5831}
58245832
5825pub fn isErrorUnionType(ip: *const InternPool, ty: Index) bool {5833pub fn isErrorUnionType(ip: *const InternPool, ty: Index) bool {
...@@ -6412,6 +6420,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -6412,6 +6420,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
6412 .slice_const_u8_sentinel_0_type,6420 .slice_const_u8_sentinel_0_type,
6413 .optional_noreturn_type,6421 .optional_noreturn_type,
6414 .anyerror_void_error_union_type,6422 .anyerror_void_error_union_type,
6423 .adhoc_inferred_error_set_type,
6415 .generic_poison_type,6424 .generic_poison_type,
6416 .empty_struct_type,6425 .empty_struct_type,
6417 => .type_type,6426 => .type_type,
...@@ -6688,7 +6697,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois...@@ -6688,7 +6697,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
6688 .bool_type => .Bool,6697 .bool_type => .Bool,
6689 .void_type => .Void,6698 .void_type => .Void,
6690 .type_type => .Type,6699 .type_type => .Type,
6691 .anyerror_type => .ErrorSet,6700 .anyerror_type, .adhoc_inferred_error_set_type => .ErrorSet,
6692 .comptime_int_type => .ComptimeInt,6701 .comptime_int_type => .ComptimeInt,
6693 .comptime_float_type => .ComptimeFloat,6702 .comptime_float_type => .ComptimeFloat,
6694 .noreturn_type => .NoReturn,6703 .noreturn_type => .NoReturn,
src/Sema.zig+121-42
...@@ -134,16 +134,19 @@ pub const default_reference_trace_len = 2;...@@ -134,16 +134,19 @@ pub const default_reference_trace_len = 2;
134134
135pub const InferredErrorSet = struct {135pub const InferredErrorSet = struct {
136 /// The function body from which this error set originates.136 /// The function body from which this error set originates.
137 /// This is `none` in the case of a comptime/inline function call, corresponding to
138 /// `InternPool.Index.adhoc_inferred_error_set_type`.
139 /// The function's resolved error set is not set until analysis of the
140 /// function body completes.
137 func: InternPool.Index,141 func: InternPool.Index,
138
139 /// All currently known errors that this error set contains. This includes142 /// All currently known errors that this error set contains. This includes
140 /// direct additions via `return error.Foo;`, and possibly also errors that143 /// direct additions via `return error.Foo;`, and possibly also errors that
141 /// are returned from any dependent functions. When the inferred error set is144 /// are returned from any dependent functions.
142 /// fully resolved, this map contains all the errors that the function might return.
143 errors: NameMap = .{},145 errors: NameMap = .{},
144
145 /// Other inferred error sets which this inferred error set should include.146 /// Other inferred error sets which this inferred error set should include.
146 inferred_error_sets: std.AutoArrayHashMapUnmanaged(InternPool.Index, void) = .{},147 inferred_error_sets: std.AutoArrayHashMapUnmanaged(InternPool.Index, void) = .{},
148 /// The regular error set created by resolving this inferred error set.
149 resolved: InternPool.Index = .none,
147150
148 pub const NameMap = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void);151 pub const NameMap = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void);
149152
...@@ -155,7 +158,7 @@ pub const InferredErrorSet = struct {...@@ -155,7 +158,7 @@ pub const InferredErrorSet = struct {
155 ) !void {158 ) !void {
156 switch (err_set_ty.toIntern()) {159 switch (err_set_ty.toIntern()) {
157 .anyerror_type => {160 .anyerror_type => {
158 ip.funcIesResolved(self.func).* = .anyerror_type;161 self.resolved = .anyerror_type;
159 },162 },
160 else => switch (ip.indexToKey(err_set_ty.toIntern())) {163 else => switch (ip.indexToKey(err_set_ty.toIntern())) {
161 .error_set_type => |error_set_type| {164 .error_set_type => |error_set_type| {
...@@ -7060,7 +7063,6 @@ fn analyzeCall(...@@ -7060,7 +7063,6 @@ fn analyzeCall(
7060 .error_set_type = error_set_ty,7063 .error_set_type = error_set_ty,
7061 .payload_type = bare_return_type.toIntern(),7064 .payload_type = bare_return_type.toIntern(),
7062 } })).toType();7065 } })).toType();
7063 ip.funcIesResolved(module_fn_index).* = .none;
7064 }7066 }
70657067
7066 // This `res2` is here instead of directly breaking from `res` due to a stage17068 // This `res2` is here instead of directly breaking from `res` due to a stage1
...@@ -7123,7 +7125,9 @@ fn analyzeCall(...@@ -7123,7 +7125,9 @@ fn analyzeCall(
7123 break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges);7125 break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges);
7124 };7126 };
71257127
7126 if (!is_comptime_call and !block.is_typeof and sema.typeOf(result).zigTypeTag(mod) != .NoReturn) {7128 if (!is_comptime_call and !block.is_typeof and
7129 sema.typeOf(result).zigTypeTag(mod) != .NoReturn)
7130 {
7127 try sema.emitDbgInline(7131 try sema.emitDbgInline(
7128 block,7132 block,
7129 module_fn_index,7133 module_fn_index,
...@@ -7137,13 +7141,23 @@ fn analyzeCall(...@@ -7137,13 +7141,23 @@ fn analyzeCall(
7137 const result_val = try sema.resolveConstMaybeUndefVal(block, .unneeded, result, "");7141 const result_val = try sema.resolveConstMaybeUndefVal(block, .unneeded, result, "");
7138 const result_interned = try result_val.intern(sema.fn_ret_ty, mod);7142 const result_interned = try result_val.intern(sema.fn_ret_ty, mod);
71397143
7144 // Transform ad-hoc inferred error set types into concrete error sets.
7145 const result_transformed = try sema.resolveAdHocInferredErrorSet(block, call_src, result_interned);
7146
7140 // TODO: check whether any external comptime memory was mutated by the7147 // TODO: check whether any external comptime memory was mutated by the
7141 // comptime function call. If so, then do not memoize the call here.7148 // comptime function call. If so, then do not memoize the call here.
7142 _ = try mod.intern(.{ .memoized_call = .{7149 _ = try mod.intern(.{ .memoized_call = .{
7143 .func = module_fn_index,7150 .func = module_fn_index,
7144 .arg_values = memoized_arg_values,7151 .arg_values = memoized_arg_values,
7145 .result = result_interned,7152 .result = result_transformed,
7146 } });7153 } });
7154
7155 break :res2 Air.internedToRef(result_transformed);
7156 }
7157
7158 if (sema.fn_ret_ty_ies) |ies| {
7159 _ = ies;
7160 @panic("TODO: resolve ad-hoc inferred error set");
7147 }7161 }
71487162
7149 break :res2 result;7163 break :res2 result;
...@@ -18237,19 +18251,30 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index)...@@ -18237,19 +18251,30 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index)
1823718251
18238fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {18252fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {
18239 const mod = sema.mod;18253 const mod = sema.mod;
18240 const gpa = sema.gpa;
18241 const ip = &mod.intern_pool;18254 const ip = &mod.intern_pool;
18242 assert(sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion);18255 assert(sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion);
18256 const err_set_ty = sema.fn_ret_ty.errorUnionSet(mod).toIntern();
18257 switch (err_set_ty) {
18258 .adhoc_inferred_error_set_type => {
18259 const ies = sema.fn_ret_ty_ies.?;
18260 assert(ies.func == .none);
18261 try addToInferredErrorSetPtr(mod, ies, sema.typeOf(uncasted_operand));
18262 },
18263 else => if (ip.isInferredErrorSetType(err_set_ty)) {
18264 const ies = sema.fn_ret_ty_ies.?;
18265 assert(ies.func == sema.func_index);
18266 try addToInferredErrorSetPtr(mod, ies, sema.typeOf(uncasted_operand));
18267 },
18268 }
18269}
1824318270
18244 if (ip.isInferredErrorSetType(sema.fn_ret_ty.errorUnionSet(mod).toIntern())) {18271fn addToInferredErrorSetPtr(mod: *Module, ies: *InferredErrorSet, op_ty: Type) !void {
18245 const ies = sema.fn_ret_ty_ies.?;18272 const gpa = mod.gpa;
18246 assert(ies.func == sema.func_index);18273 const ip = &mod.intern_pool;
18247 const op_ty = sema.typeOf(uncasted_operand);18274 switch (op_ty.zigTypeTag(mod)) {
18248 switch (op_ty.zigTypeTag(mod)) {18275 .ErrorSet => try ies.addErrorSet(op_ty, ip, gpa),
18249 .ErrorSet => try ies.addErrorSet(op_ty, ip, gpa),18276 .ErrorUnion => try ies.addErrorSet(op_ty.errorUnionSet(mod), ip, gpa),
18250 .ErrorUnion => try ies.addErrorSet(op_ty.errorUnionSet(mod), ip, gpa),18277 else => {},
18251 else => {},
18252 }
18253 }18278 }
18254}18279}
1825518280
...@@ -27936,6 +27961,14 @@ fn coerceInMemoryAllowedErrorSets(...@@ -27936,6 +27961,14 @@ fn coerceInMemoryAllowedErrorSets(
27936 return .ok;27961 return .ok;
27937 }27962 }
2793827963
27964 if (dest_ty.toIntern() == .adhoc_inferred_error_set_type) {
27965 // We are trying to coerce an error set to the current function's
27966 // inferred error set.
27967 const dst_ies = sema.fn_ret_ty_ies.?;
27968 try dst_ies.addErrorSet(src_ty, ip, gpa);
27969 return .ok;
27970 }
27971
27939 if (ip.isInferredErrorSetType(dest_ty.toIntern())) {27972 if (ip.isInferredErrorSetType(dest_ty.toIntern())) {
27940 const dst_ies_func_index = ip.iesFuncIndex(dest_ty.toIntern());27973 const dst_ies_func_index = ip.iesFuncIndex(dest_ty.toIntern());
27941 if (sema.fn_ret_ty_ies) |dst_ies| {27974 if (sema.fn_ret_ty_ies) |dst_ies| {
...@@ -27946,7 +27979,6 @@ fn coerceInMemoryAllowedErrorSets(...@@ -27946,7 +27979,6 @@ fn coerceInMemoryAllowedErrorSets(
27946 return .ok;27979 return .ok;
27947 }27980 }
27948 }27981 }
27949
27950 switch (try sema.resolveInferredErrorSet(block, dest_src, dest_ty.toIntern())) {27982 switch (try sema.resolveInferredErrorSet(block, dest_src, dest_ty.toIntern())) {
27951 // isAnyError might have changed from a false negative to a true27983 // isAnyError might have changed from a false negative to a true
27952 // positive after resolution.27984 // positive after resolution.
...@@ -30551,21 +30583,25 @@ fn analyzeIsNonErrComptimeOnly(...@@ -30551,21 +30583,25 @@ fn analyzeIsNonErrComptimeOnly(
30551 else => |i| if (ip.indexToKey(i).error_set_type.names.len != 0) break :blk,30583 else => |i| if (ip.indexToKey(i).error_set_type.names.len != 0) break :blk,
30552 }30584 }
30553 if (maybe_operand_val == null) {30585 if (maybe_operand_val == null) {
30554 if (sema.fn_ret_ty_ies) |ies| if (ies.func == func_index) {30586 if (sema.fn_ret_ty_ies) |ies| {
30555 // Try to avoid resolving inferred error set if possible.30587 if (set_ty == .adhoc_inferred_error_set_type or
30556 for (ies.inferred_error_sets.keys()) |other_ies_index| {30588 ies.func == func_index)
30557 if (set_ty == other_ies_index) continue;30589 {
30558 const other_resolved =30590 // Try to avoid resolving inferred error set if possible.
30559 try sema.resolveInferredErrorSet(block, src, other_ies_index);30591 for (ies.inferred_error_sets.keys()) |other_ies_index| {
30560 if (other_resolved == .anyerror_type) {30592 if (set_ty == other_ies_index) continue;
30561 ip.funcIesResolved(func_index).* = .anyerror_type;30593 const other_resolved =
30562 break :blk;30594 try sema.resolveInferredErrorSet(block, src, other_ies_index);
30595 if (other_resolved == .anyerror_type) {
30596 ip.funcIesResolved(func_index).* = .anyerror_type;
30597 break :blk;
30598 }
30599 if (ip.indexToKey(other_resolved).error_set_type.names.len != 0)
30600 break :blk;
30563 }30601 }
30564 if (ip.indexToKey(other_resolved).error_set_type.names.len != 0)30602 return .bool_true;
30565 break :blk;
30566 }30603 }
30567 return .bool_true;30604 }
30568 };
30569 const resolved_ty = try sema.resolveInferredErrorSet(block, src, set_ty);30605 const resolved_ty = try sema.resolveInferredErrorSet(block, src, set_ty);
30570 if (resolved_ty == .anyerror_type)30606 if (resolved_ty == .anyerror_type)
30571 break :blk;30607 break :blk;
...@@ -31520,18 +31556,30 @@ fn wrapErrorUnionSet(...@@ -31520,18 +31556,30 @@ fn wrapErrorUnionSet(
31520 const inst_ty = sema.typeOf(inst);31556 const inst_ty = sema.typeOf(inst);
31521 const dest_err_set_ty = dest_ty.errorUnionSet(mod);31557 const dest_err_set_ty = dest_ty.errorUnionSet(mod);
31522 if (try sema.resolveMaybeUndefVal(inst)) |val| {31558 if (try sema.resolveMaybeUndefVal(inst)) |val| {
31559 const expected_name = mod.intern_pool.indexToKey(val.toIntern()).err.name;
31523 switch (dest_err_set_ty.toIntern()) {31560 switch (dest_err_set_ty.toIntern()) {
31524 .anyerror_type => {},31561 .anyerror_type => {},
31562 .adhoc_inferred_error_set_type => ok: {
31563 const ies = sema.fn_ret_ty_ies.?;
31564 switch (ies.resolved) {
31565 .anyerror_type => break :ok,
31566 .none => if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, dest_err_set_ty, inst_ty, inst_src, inst_src)) {
31567 break :ok;
31568 },
31569 else => |i| if (ip.indexToKey(i).error_set_type.nameIndex(ip, expected_name) != null) {
31570 break :ok;
31571 },
31572 }
31573 return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);
31574 },
31525 else => switch (ip.indexToKey(dest_err_set_ty.toIntern())) {31575 else => switch (ip.indexToKey(dest_err_set_ty.toIntern())) {
31526 .error_set_type => |error_set_type| ok: {31576 .error_set_type => |error_set_type| ok: {
31527 const expected_name = mod.intern_pool.indexToKey(val.toIntern()).err.name;
31528 if (error_set_type.nameIndex(ip, expected_name) != null) break :ok;31577 if (error_set_type.nameIndex(ip, expected_name) != null) break :ok;
31529 return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);31578 return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);
31530 },31579 },
31531 .inferred_error_set_type => |func_index| ok: {31580 .inferred_error_set_type => |func_index| ok: {
31532 // We carefully do this in an order that avoids unnecessarily31581 // We carefully do this in an order that avoids unnecessarily
31533 // resolving the destination error set type.31582 // resolving the destination error set type.
31534 const expected_name = mod.intern_pool.indexToKey(val.toIntern()).err.name;
31535 switch (ip.funcIesResolved(func_index).*) {31583 switch (ip.funcIesResolved(func_index).*) {
31536 .anyerror_type => break :ok,31584 .anyerror_type => break :ok,
31537 .none => if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, dest_err_set_ty, inst_ty, inst_src, inst_src)) {31585 .none => if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, dest_err_set_ty, inst_ty, inst_src, inst_src)) {
...@@ -31549,9 +31597,7 @@ fn wrapErrorUnionSet(...@@ -31549,9 +31597,7 @@ fn wrapErrorUnionSet(
31549 }31597 }
31550 return sema.addConstant((try mod.intern(.{ .error_union = .{31598 return sema.addConstant((try mod.intern(.{ .error_union = .{
31551 .ty = dest_ty.toIntern(),31599 .ty = dest_ty.toIntern(),
31552 .val = .{31600 .val = .{ .err_name = expected_name },
31553 .err_name = mod.intern_pool.indexToKey(try val.intern(dest_err_set_ty, mod)).err.name,
31554 },
31555 } })).toValue());31601 } })).toValue());
31556 }31602 }
3155731603
...@@ -33033,7 +33079,11 @@ pub fn resolveFnTypes(sema: *Sema, block: *Block, src: LazySrcLoc, fn_ty: Type)...@@ -33033,7 +33079,11 @@ pub fn resolveFnTypes(sema: *Sema, block: *Block, src: LazySrcLoc, fn_ty: Type)
33033 const ip = &mod.intern_pool;33079 const ip = &mod.intern_pool;
33034 const fn_ty_info = mod.typeToFunc(fn_ty).?;33080 const fn_ty_info = mod.typeToFunc(fn_ty).?;
3303533081
33036 if (sema.fn_ret_ty_ies) |ies| try sema.resolveInferredErrorSetPtr(block, src, ies);33082 if (sema.fn_ret_ty_ies) |ies| {
33083 try sema.resolveInferredErrorSetPtr(block, src, ies);
33084 assert(ies.resolved != .none);
33085 ip.funcIesResolved(sema.func_index).* = ies.resolved;
33086 }
3303733087
33038 try sema.resolveTypeFully(fn_ty_info.return_type.toType());33088 try sema.resolveTypeFully(fn_ty_info.return_type.toType());
3303933089
...@@ -33565,6 +33615,7 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -33565,6 +33615,7 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
33565 .bool,33615 .bool,
33566 .void,33616 .void,
33567 .anyerror,33617 .anyerror,
33618 .adhoc_inferred_error_set,
33568 .noreturn,33619 .noreturn,
33569 .generic_poison,33620 .generic_poison,
33570 .atomic_order,33621 .atomic_order,
...@@ -33815,6 +33866,7 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {...@@ -33815,6 +33866,7 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
33815 .void_type,33866 .void_type,
33816 .type_type,33867 .type_type,
33817 .anyerror_type,33868 .anyerror_type,
33869 .adhoc_inferred_error_set_type,
33818 .comptime_int_type,33870 .comptime_int_type,
33819 .comptime_float_type,33871 .comptime_float_type,
33820 .noreturn_type,33872 .noreturn_type,
...@@ -34032,8 +34084,7 @@ fn resolveInferredErrorSetPtr(...@@ -34032,8 +34084,7 @@ fn resolveInferredErrorSetPtr(
34032 const mod = sema.mod;34084 const mod = sema.mod;
34033 const ip = &mod.intern_pool;34085 const ip = &mod.intern_pool;
3403434086
34035 const func = mod.funcInfo(ies.func);34087 if (ies.resolved != .none) return;
34036 if (func.resolvedErrorSet(ip).* != .none) return;
3403734088
34038 const ies_index = ip.errorUnionSet(sema.fn_ret_ty.toIntern());34089 const ies_index = ip.errorUnionSet(sema.fn_ret_ty.toIntern());
3403934090
...@@ -34041,7 +34092,7 @@ fn resolveInferredErrorSetPtr(...@@ -34041,7 +34092,7 @@ fn resolveInferredErrorSetPtr(
34041 if (ies_index == other_ies_index) continue;34092 if (ies_index == other_ies_index) continue;
34042 switch (try sema.resolveInferredErrorSet(block, src, other_ies_index)) {34093 switch (try sema.resolveInferredErrorSet(block, src, other_ies_index)) {
34043 .anyerror_type => {34094 .anyerror_type => {
34044 func.resolvedErrorSet(ip).* = .anyerror_type;34095 ies.resolved = .anyerror_type;
34045 return;34096 return;
34046 },34097 },
34047 else => |error_set_ty_index| {34098 else => |error_set_ty_index| {
...@@ -34054,7 +34105,33 @@ fn resolveInferredErrorSetPtr(...@@ -34054,7 +34105,33 @@ fn resolveInferredErrorSetPtr(
34054 }34105 }
3405534106
34056 const resolved_error_set_ty = try mod.errorSetFromUnsortedNames(ies.errors.keys());34107 const resolved_error_set_ty = try mod.errorSetFromUnsortedNames(ies.errors.keys());
34057 func.resolvedErrorSet(ip).* = resolved_error_set_ty.toIntern();34108 ies.resolved = resolved_error_set_ty.toIntern();
34109}
34110
34111fn resolveAdHocInferredErrorSet(
34112 sema: *Sema,
34113 block: *Block,
34114 src: LazySrcLoc,
34115 value: InternPool.Index,
34116) CompileError!InternPool.Index {
34117 const ies = sema.fn_ret_ty_ies orelse return value;
34118 const mod = sema.mod;
34119 const gpa = sema.gpa;
34120 const ip = &mod.intern_pool;
34121 const ty = ip.typeOf(value);
34122 const error_union_info = switch (ip.indexToKey(ty)) {
34123 .error_union_type => |x| x,
34124 else => return value,
34125 };
34126 if (error_union_info.error_set_type != .adhoc_inferred_error_set_type)
34127 return value;
34128
34129 try sema.resolveInferredErrorSetPtr(block, src, ies);
34130 const new_ty = try ip.get(gpa, .{ .error_union_type = .{
34131 .error_set_type = ies.resolved,
34132 .payload_type = error_union_info.payload_type,
34133 } });
34134 return ip.getCoerced(gpa, value, new_ty);
34058}34135}
3405934136
34060fn resolveInferredErrorSetTy(34137fn resolveInferredErrorSetTy(
...@@ -35037,6 +35114,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -35037,6 +35114,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
35037 .bool_type,35114 .bool_type,
35038 .type_type,35115 .type_type,
35039 .anyerror_type,35116 .anyerror_type,
35117 .adhoc_inferred_error_set_type,
35040 .comptime_int_type,35118 .comptime_int_type,
35041 .comptime_float_type,35119 .comptime_float_type,
35042 .enum_literal_type,35120 .enum_literal_type,
...@@ -35692,6 +35770,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -35692,6 +35770,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
35692 .prefetch_options,35770 .prefetch_options,
35693 .export_options,35771 .export_options,
35694 .extern_options,35772 .extern_options,
35773 .adhoc_inferred_error_set,
35695 => false,35774 => false,
3569635775
35697 .type,35776 .type,
src/Zir.zig+1
...@@ -2087,6 +2087,7 @@ pub const Inst = struct {...@@ -2087,6 +2087,7 @@ pub const Inst = struct {
2087 slice_const_u8_sentinel_0_type = @intFromEnum(InternPool.Index.slice_const_u8_sentinel_0_type),2087 slice_const_u8_sentinel_0_type = @intFromEnum(InternPool.Index.slice_const_u8_sentinel_0_type),
2088 optional_noreturn_type = @intFromEnum(InternPool.Index.optional_noreturn_type),2088 optional_noreturn_type = @intFromEnum(InternPool.Index.optional_noreturn_type),
2089 anyerror_void_error_union_type = @intFromEnum(InternPool.Index.anyerror_void_error_union_type),2089 anyerror_void_error_union_type = @intFromEnum(InternPool.Index.anyerror_void_error_union_type),
2090 adhoc_inferred_error_set_type = @intFromEnum(InternPool.Index.adhoc_inferred_error_set_type),
2090 generic_poison_type = @intFromEnum(InternPool.Index.generic_poison_type),2091 generic_poison_type = @intFromEnum(InternPool.Index.generic_poison_type),
2091 empty_struct_type = @intFromEnum(InternPool.Index.empty_struct_type),2092 empty_struct_type = @intFromEnum(InternPool.Index.empty_struct_type),
2092 undef = @intFromEnum(InternPool.Index.undef),2093 undef = @intFromEnum(InternPool.Index.undef),
src/type.zig+14-3
...@@ -292,6 +292,7 @@ pub const Type = struct {...@@ -292,6 +292,7 @@ pub const Type = struct {
292 .comptime_int,292 .comptime_int,
293 .comptime_float,293 .comptime_float,
294 .noreturn,294 .noreturn,
295 .adhoc_inferred_error_set,
295 => return writer.writeAll(@tagName(s)),296 => return writer.writeAll(@tagName(s)),
296297
297 .null,298 .null,
...@@ -533,6 +534,7 @@ pub const Type = struct {...@@ -533,6 +534,7 @@ pub const Type = struct {
533 .c_longdouble,534 .c_longdouble,
534 .bool,535 .bool,
535 .anyerror,536 .anyerror,
537 .adhoc_inferred_error_set,
536 .anyopaque,538 .anyopaque,
537 .atomic_order,539 .atomic_order,
538 .atomic_rmw_op,540 .atomic_rmw_op,
...@@ -696,6 +698,7 @@ pub const Type = struct {...@@ -696,6 +698,7 @@ pub const Type = struct {
696 => true,698 => true,
697699
698 .anyerror,700 .anyerror,
701 .adhoc_inferred_error_set,
699 .anyopaque,702 .anyopaque,
700 .atomic_order,703 .atomic_order,
701 .atomic_rmw_op,704 .atomic_rmw_op,
...@@ -954,7 +957,9 @@ pub const Type = struct {...@@ -954,7 +957,9 @@ pub const Type = struct {
954 },957 },
955958
956 // TODO revisit this when we have the concept of the error tag type959 // TODO revisit this when we have the concept of the error tag type
957 .anyerror => return AbiAlignmentAdvanced{ .scalar = 2 },960 .anyerror,
961 .adhoc_inferred_error_set,
962 => return AbiAlignmentAdvanced{ .scalar = 2 },
958963
959 .void,964 .void,
960 .type,965 .type,
...@@ -1418,7 +1423,9 @@ pub const Type = struct {...@@ -1418,7 +1423,9 @@ pub const Type = struct {
1418 => return AbiSizeAdvanced{ .scalar = 0 },1423 => return AbiSizeAdvanced{ .scalar = 0 },
14191424
1420 // TODO revisit this when we have the concept of the error tag type1425 // TODO revisit this when we have the concept of the error tag type
1421 .anyerror => return AbiSizeAdvanced{ .scalar = 2 },1426 .anyerror,
1427 .adhoc_inferred_error_set,
1428 => return AbiSizeAdvanced{ .scalar = 2 },
14221429
1423 .prefetch_options => unreachable, // missing call to resolveTypeFields1430 .prefetch_options => unreachable, // missing call to resolveTypeFields
1424 .export_options => unreachable, // missing call to resolveTypeFields1431 .export_options => unreachable, // missing call to resolveTypeFields
...@@ -1661,7 +1668,9 @@ pub const Type = struct {...@@ -1661,7 +1668,9 @@ pub const Type = struct {
1661 .void => return 0,1668 .void => return 0,
16621669
1663 // TODO revisit this when we have the concept of the error tag type1670 // TODO revisit this when we have the concept of the error tag type
1664 .anyerror => return 16,1671 .anyerror,
1672 .adhoc_inferred_error_set,
1673 => return 16,
16651674
1666 .anyopaque => unreachable,1675 .anyopaque => unreachable,
1667 .type => unreachable,1676 .type => unreachable,
...@@ -2503,6 +2512,7 @@ pub const Type = struct {...@@ -2503,6 +2512,7 @@ pub const Type = struct {
2503 .export_options,2512 .export_options,
2504 .extern_options,2513 .extern_options,
2505 .type_info,2514 .type_info,
2515 .adhoc_inferred_error_set,
2506 => return null,2516 => return null,
25072517
2508 .void => return Value.void,2518 .void => return Value.void,
...@@ -2697,6 +2707,7 @@ pub const Type = struct {...@@ -2697,6 +2707,7 @@ pub const Type = struct {
2697 .bool,2707 .bool,
2698 .void,2708 .void,
2699 .anyerror,2709 .anyerror,
2710 .adhoc_inferred_error_set,
2700 .noreturn,2711 .noreturn,
2701 .generic_poison,2712 .generic_poison,
2702 .atomic_order,2713 .atomic_order,