| ... | @@ -594,6 +594,13 @@ pub const Key = union(enum) { | ... | @@ -594,6 +594,13 @@ pub const Key = union(enum) { |
| 594 | /// In the case of a generic function, this type will potentially have fewer parameters | 594 | /// In the case of a generic function, this type will potentially have fewer parameters |
| 595 | /// than the generic owner's type, because the comptime parameters will be deleted. | 595 | /// than the generic owner's type, because the comptime parameters will be deleted. |
| 596 | ty: Index, | 596 | ty: Index, |
| | 597 | /// If this is a function body that has been coerced to a different type, for example |
| | 598 | /// ``` |
| | 599 | /// fn f2() !void {} |
| | 600 | /// const f: fn()anyerror!void = f2; |
| | 601 | /// ``` |
| | 602 | /// then it contains the original type of the function body. |
| | 603 | uncoerced_ty: Index, |
| 597 | /// Index into extra array of the `FuncAnalysis` corresponding to this function. | 604 | /// Index into extra array of the `FuncAnalysis` corresponding to this function. |
| 598 | /// Used for mutating that data. | 605 | /// Used for mutating that data. |
| 599 | analysis_extra_index: u32, | 606 | analysis_extra_index: u32, |
| ... | @@ -990,11 +997,15 @@ pub const Key = union(enum) { | ... | @@ -990,11 +997,15 @@ pub const Key = union(enum) { |
| 990 | // otherwise we would get false negatives for interning generic | 997 | // otherwise we would get false negatives for interning generic |
| 991 | // function instances which have inferred error sets. | 998 | // function instances which have inferred error sets. |
| 992 | | 999 | |
| 993 | if (func.generic_owner == .none and func.resolved_error_set_extra_index == 0) | 1000 | if (func.generic_owner == .none and func.resolved_error_set_extra_index == 0) { |
| 994 | return Hash.hash(seed, asBytes(&func.owner_decl) ++ asBytes(&func.ty)); | 1001 | const bytes = asBytes(&func.owner_decl) ++ asBytes(&func.ty) ++ |
| | 1002 | [1]u8{@intFromBool(func.uncoerced_ty == func.ty)}; |
| | 1003 | return Hash.hash(seed, bytes); |
| | 1004 | } |
| 995 | | 1005 | |
| 996 | var hasher = Hash.init(seed); | 1006 | var hasher = Hash.init(seed); |
| 997 | std.hash.autoHash(&hasher, func.generic_owner); | 1007 | std.hash.autoHash(&hasher, func.generic_owner); |
| | 1008 | std.hash.autoHash(&hasher, func.uncoerced_ty == func.ty); |
| 998 | for (func.comptime_args.get(ip)) |arg| std.hash.autoHash(&hasher, arg); | 1009 | for (func.comptime_args.get(ip)) |arg| std.hash.autoHash(&hasher, arg); |
| 999 | if (func.resolved_error_set_extra_index == 0) { | 1010 | if (func.resolved_error_set_extra_index == 0) { |
| 1000 | std.hash.autoHash(&hasher, func.ty); | 1011 | std.hash.autoHash(&hasher, func.ty); |
| ... | @@ -1122,6 +1133,12 @@ pub const Key = union(enum) { | ... | @@ -1122,6 +1133,12 @@ pub const Key = union(enum) { |
| 1122 | )) return false; | 1133 | )) return false; |
| 1123 | } | 1134 | } |
| 1124 | | 1135 | |
| | 1136 | if ((a_info.ty == a_info.uncoerced_ty) != |
| | 1137 | (b_info.ty == b_info.uncoerced_ty)) |
| | 1138 | { |
| | 1139 | return false; |
| | 1140 | } |
| | 1141 | |
| 1125 | if (a_info.ty == b_info.ty) | 1142 | if (a_info.ty == b_info.ty) |
| 1126 | return true; | 1143 | return true; |
| 1127 | | 1144 | |
| ... | @@ -3371,6 +3388,7 @@ fn extraFuncDecl(ip: *const InternPool, extra_index: u32) Key.Func { | ... | @@ -3371,6 +3388,7 @@ fn extraFuncDecl(ip: *const InternPool, extra_index: u32) Key.Func { |
| 3371 | const func_decl = ip.extraDataTrail(P, extra_index); | 3388 | const func_decl = ip.extraDataTrail(P, extra_index); |
| 3372 | return .{ | 3389 | return .{ |
| 3373 | .ty = func_decl.data.ty, | 3390 | .ty = func_decl.data.ty, |
| | 3391 | .uncoerced_ty = func_decl.data.ty, |
| 3374 | .analysis_extra_index = extra_index + std.meta.fieldIndex(P, "analysis").?, | 3392 | .analysis_extra_index = extra_index + std.meta.fieldIndex(P, "analysis").?, |
| 3375 | .zir_body_inst_extra_index = extra_index + std.meta.fieldIndex(P, "zir_body_inst").?, | 3393 | .zir_body_inst_extra_index = extra_index + std.meta.fieldIndex(P, "zir_body_inst").?, |
| 3376 | .resolved_error_set_extra_index = if (func_decl.data.analysis.inferred_error_set) func_decl.end else 0, | 3394 | .resolved_error_set_extra_index = if (func_decl.data.analysis.inferred_error_set) func_decl.end else 0, |
| ... | @@ -3392,6 +3410,7 @@ fn extraFuncInstance(ip: *const InternPool, extra_index: u32) Key.Func { | ... | @@ -3392,6 +3410,7 @@ fn extraFuncInstance(ip: *const InternPool, extra_index: u32) Key.Func { |
| 3392 | const func_decl = ip.funcDeclInfo(fi.data.generic_owner); | 3410 | const func_decl = ip.funcDeclInfo(fi.data.generic_owner); |
| 3393 | return .{ | 3411 | return .{ |
| 3394 | .ty = fi.data.ty, | 3412 | .ty = fi.data.ty, |
| | 3413 | .uncoerced_ty = fi.data.ty, |
| 3395 | .analysis_extra_index = extra_index + std.meta.fieldIndex(P, "analysis").?, | 3414 | .analysis_extra_index = extra_index + std.meta.fieldIndex(P, "analysis").?, |
| 3396 | .zir_body_inst_extra_index = func_decl.zir_body_inst_extra_index, | 3415 | .zir_body_inst_extra_index = func_decl.zir_body_inst_extra_index, |
| 3397 | .resolved_error_set_extra_index = if (fi.data.analysis.inferred_error_set) fi.end else 0, | 3416 | .resolved_error_set_extra_index = if (fi.data.analysis.inferred_error_set) fi.end else 0, |
| ... | @@ -4800,6 +4819,8 @@ pub fn getFuncInstanceIes( | ... | @@ -4800,6 +4819,8 @@ pub fn getFuncInstanceIes( |
| 4800 | assert(arg.bare_return_type != .none); | 4819 | assert(arg.bare_return_type != .none); |
| 4801 | for (arg.param_types) |param_type| assert(param_type != .none); | 4820 | for (arg.param_types) |param_type| assert(param_type != .none); |
| 4802 | | 4821 | |
| | 4822 | const generic_owner = unwrapCoercedFunc(ip, arg.generic_owner); |
| | 4823 | |
| 4803 | // The strategy here is to add the function decl unconditionally, then to | 4824 | // The strategy here is to add the function decl unconditionally, then to |
| 4804 | // ask if it already exists, and if so, revert the lengths of the mutated | 4825 | // ask if it already exists, and if so, revert the lengths of the mutated |
| 4805 | // arrays. This is similar to what `getOrPutTrailingString` does. | 4826 | // arrays. This is similar to what `getOrPutTrailingString` does. |
| ... | @@ -4835,7 +4856,7 @@ pub fn getFuncInstanceIes( | ... | @@ -4835,7 +4856,7 @@ pub fn getFuncInstanceIes( |
| 4835 | .owner_decl = undefined, | 4856 | .owner_decl = undefined, |
| 4836 | .ty = func_ty, | 4857 | .ty = func_ty, |
| 4837 | .branch_quota = 0, | 4858 | .branch_quota = 0, |
| 4838 | .generic_owner = arg.generic_owner, | 4859 | .generic_owner = generic_owner, |
| 4839 | }); | 4860 | }); |
| 4840 | ip.extra.appendAssumeCapacity(@intFromEnum(Index.none)); // resolved error set | 4861 | ip.extra.appendAssumeCapacity(@intFromEnum(Index.none)); // resolved error set |
| 4841 | ip.extra.appendSliceAssumeCapacity(@ptrCast(arg.comptime_args)); | 4862 | ip.extra.appendSliceAssumeCapacity(@ptrCast(arg.comptime_args)); |
| ... | @@ -4908,7 +4929,7 @@ pub fn getFuncInstanceIes( | ... | @@ -4908,7 +4929,7 @@ pub fn getFuncInstanceIes( |
| 4908 | return finishFuncInstance( | 4929 | return finishFuncInstance( |
| 4909 | ip, | 4930 | ip, |
| 4910 | gpa, | 4931 | gpa, |
| 4911 | arg.generic_owner, | 4932 | generic_owner, |
| 4912 | func_index, | 4933 | func_index, |
| 4913 | func_extra_index, | 4934 | func_extra_index, |
| 4914 | arg.generation, | 4935 | arg.generation, |
| ... | @@ -7050,6 +7071,17 @@ pub fn funcIesResolved(ip: *const InternPool, func_index: Index) *Index { | ... | @@ -7050,6 +7071,17 @@ pub fn funcIesResolved(ip: *const InternPool, func_index: Index) *Index { |
| 7050 | const extra_index = switch (tags[@intFromEnum(func_index)]) { | 7071 | const extra_index = switch (tags[@intFromEnum(func_index)]) { |
| 7051 | .func_decl => func_start + @typeInfo(Tag.FuncDecl).Struct.fields.len, | 7072 | .func_decl => func_start + @typeInfo(Tag.FuncDecl).Struct.fields.len, |
| 7052 | .func_instance => func_start + @typeInfo(Tag.FuncInstance).Struct.fields.len, | 7073 | .func_instance => func_start + @typeInfo(Tag.FuncInstance).Struct.fields.len, |
| | 7074 | .func_coerced => i: { |
| | 7075 | const uncoerced_func_index: Index = @enumFromInt(ip.extra.items[ |
| | 7076 | func_start + std.meta.fieldIndex(Tag.FuncCoerced, "func").? |
| | 7077 | ]); |
| | 7078 | const uncoerced_func_start = datas[@intFromEnum(uncoerced_func_index)]; |
| | 7079 | break :i switch (tags[@intFromEnum(uncoerced_func_index)]) { |
| | 7080 | .func_decl => uncoerced_func_start + @typeInfo(Tag.FuncDecl).Struct.fields.len, |
| | 7081 | .func_instance => uncoerced_func_start + @typeInfo(Tag.FuncInstance).Struct.fields.len, |
| | 7082 | else => unreachable, |
| | 7083 | }; |
| | 7084 | }, |
| 7053 | else => unreachable, | 7085 | else => unreachable, |
| 7054 | }; | 7086 | }; |
| 7055 | return @ptrCast(&ip.extra.items[extra_index]); | 7087 | return @ptrCast(&ip.extra.items[extra_index]); |