| ... | ... | @@ -4671,22 +4671,6 @@ const GenericCallAdapter = struct { |
| 4671 | 4671 | } |
| 4672 | 4672 | }; |
| 4673 | 4673 | |
| 4674 | | const GenericRemoveAdapter = struct { |
| 4675 | | precomputed_hash: u64, |
| 4676 | | |
| 4677 | | pub fn eql(ctx: @This(), adapted_key: *Module.Fn, other_key: *Module.Fn) bool { |
| 4678 | | _ = ctx; |
| 4679 | | return adapted_key == other_key; |
| 4680 | | } |
| 4681 | | |
| 4682 | | /// The implementation of the hash is in semantic analysis of function calls, so |
| 4683 | | /// that any errors when computing the hash can be properly reported. |
| 4684 | | pub fn hash(ctx: @This(), adapted_key: *Module.Fn) u64 { |
| 4685 | | _ = adapted_key; |
| 4686 | | return ctx.precomputed_hash; |
| 4687 | | } |
| 4688 | | }; |
| 4689 | | |
| 4690 | 4674 | fn analyzeCall( |
| 4691 | 4675 | sema: *Sema, |
| 4692 | 4676 | block: *Block, |
| ... | ... | @@ -5200,15 +5184,15 @@ fn instantiateGenericCall( |
| 5200 | 5184 | .comptime_tvs = comptime_tvs, |
| 5201 | 5185 | .target = target, |
| 5202 | 5186 | }; |
| 5203 | | const gop = try mod.monomorphed_funcs.getOrPutContextAdapted(gpa, {}, adapter, .{ .target = target }); |
| 5187 | const gop = try mod.monomorphed_funcs.getOrPutAdapted(gpa, {}, adapter); |
| 5204 | 5188 | const callee = if (!gop.found_existing) callee: { |
| 5205 | 5189 | const new_module_func = try gpa.create(Module.Fn); |
| 5190 | // This ensures that we can operate on the hash map before the Module.Fn |
| 5191 | // struct is fully initialized. |
| 5192 | new_module_func.hash = precomputed_hash; |
| 5206 | 5193 | gop.key_ptr.* = new_module_func; |
| 5207 | 5194 | errdefer gpa.destroy(new_module_func); |
| 5208 | | const remove_adapter: GenericRemoveAdapter = .{ |
| 5209 | | .precomputed_hash = precomputed_hash, |
| 5210 | | }; |
| 5211 | | errdefer assert(mod.monomorphed_funcs.removeAdapted(new_module_func, remove_adapter)); |
| 5195 | errdefer assert(mod.monomorphed_funcs.remove(new_module_func)); |
| 5212 | 5196 | |
| 5213 | 5197 | try namespace.anon_decls.ensureUnusedCapacity(gpa, 1); |
| 5214 | 5198 | |
| ... | ... | @@ -6494,12 +6478,14 @@ fn funcCommon( |
| 6494 | 6478 | param_name.* = try sema.gpa.dupeZ(u8, block.params.items[i].name); |
| 6495 | 6479 | } |
| 6496 | 6480 | |
| 6481 | const hash = new_func.hash; |
| 6497 | 6482 | const fn_payload = try sema.arena.create(Value.Payload.Function); |
| 6498 | 6483 | new_func.* = .{ |
| 6499 | 6484 | .state = anal_state, |
| 6500 | 6485 | .zir_body_inst = func_inst, |
| 6501 | 6486 | .owner_decl = sema.owner_decl, |
| 6502 | 6487 | .comptime_args = comptime_args, |
| 6488 | .hash = hash, |
| 6503 | 6489 | .lbrace_line = src_locs.lbrace_line, |
| 6504 | 6490 | .rbrace_line = src_locs.rbrace_line, |
| 6505 | 6491 | .lbrace_column = @truncate(u16, src_locs.columns), |
| ... | ... | @@ -19987,18 +19973,39 @@ fn analyzeIsNonErr( |
| 19987 | 19973 | if (ot == .ErrorSet) return Air.Inst.Ref.bool_false; |
| 19988 | 19974 | assert(ot == .ErrorUnion); |
| 19989 | 19975 | |
| 19976 | if (Air.refToIndex(operand)) |operand_inst| { |
| 19977 | const air_tags = sema.air_instructions.items(.tag); |
| 19978 | if (air_tags[operand_inst] == .wrap_errunion_payload) { |
| 19979 | return Air.Inst.Ref.bool_true; |
| 19980 | } |
| 19981 | } |
| 19982 | |
| 19983 | const maybe_operand_val = try sema.resolveMaybeUndefVal(block, src, operand); |
| 19984 | |
| 19990 | 19985 | // exception if the error union error set is known to be empty, |
| 19991 | 19986 | // we allow the comparison but always make it comptime known. |
| 19992 | 19987 | const set_ty = operand_ty.errorUnionSet(); |
| 19993 | 19988 | switch (set_ty.tag()) { |
| 19994 | | .anyerror, .error_set_inferred => {}, |
| 19989 | .anyerror => {}, |
| 19990 | .error_set_inferred => blk: { |
| 19991 | // If the error set is empty, we must return a comptime true or false. |
| 19992 | // However we want to avoid unnecessarily resolving an inferred error set |
| 19993 | // in case it is already non-empty. |
| 19994 | const ies = set_ty.castTag(.error_set_inferred).?.data; |
| 19995 | if (ies.is_anyerror) break :blk; |
| 19996 | if (ies.errors.count() != 0) break :blk; |
| 19997 | if (maybe_operand_val == null) { |
| 19998 | try sema.resolveInferredErrorSet(block, src, ies); |
| 19999 | if (ies.is_anyerror) break :blk; |
| 20000 | if (ies.errors.count() == 0) return Air.Inst.Ref.bool_true; |
| 20001 | } |
| 20002 | }, |
| 19995 | 20003 | else => if (set_ty.errorSetNames().len == 0) return Air.Inst.Ref.bool_true, |
| 19996 | 20004 | } |
| 19997 | 20005 | |
| 19998 | | const result_ty = Type.bool; |
| 19999 | | if (try sema.resolveMaybeUndefVal(block, src, operand)) |err_union| { |
| 20006 | if (maybe_operand_val) |err_union| { |
| 20000 | 20007 | if (err_union.isUndef()) { |
| 20001 | | return sema.addConstUndef(result_ty); |
| 20008 | return sema.addConstUndef(Type.bool); |
| 20002 | 20009 | } |
| 20003 | 20010 | if (err_union.getError() == null) { |
| 20004 | 20011 | return Air.Inst.Ref.bool_true; |
| ... | ... | @@ -20583,6 +20590,7 @@ fn wrapErrorUnionPayload( |
| 20583 | 20590 | return sema.addConstant(dest_ty, try Value.Tag.eu_payload.create(sema.arena, val)); |
| 20584 | 20591 | } |
| 20585 | 20592 | try sema.requireRuntimeBlock(block, inst_src); |
| 20593 | try sema.queueFullTypeResolution(dest_payload_ty); |
| 20586 | 20594 | return block.addTyOp(.wrap_errunion_payload, dest_ty, coerced); |
| 20587 | 20595 | } |
| 20588 | 20596 | |
| ... | ... | @@ -21372,6 +21380,9 @@ fn resolveStructFully( |
| 21372 | 21380 | try sema.resolveTypeFully(block, src, field.ty); |
| 21373 | 21381 | } |
| 21374 | 21382 | struct_obj.status = .fully_resolved; |
| 21383 | |
| 21384 | // And let's not forget comptime-only status. |
| 21385 | _ = try sema.typeRequiresComptime(block, src, ty); |
| 21375 | 21386 | } |
| 21376 | 21387 | |
| 21377 | 21388 | fn resolveUnionFully( |
| ... | ... | @@ -21395,6 +21406,9 @@ fn resolveUnionFully( |
| 21395 | 21406 | try sema.resolveTypeFully(block, src, field.ty); |
| 21396 | 21407 | } |
| 21397 | 21408 | union_obj.status = .fully_resolved; |
| 21409 | |
| 21410 | // And let's not forget comptime-only status. |
| 21411 | _ = try sema.typeRequiresComptime(block, src, ty); |
| 21398 | 21412 | } |
| 21399 | 21413 | |
| 21400 | 21414 | pub fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!Type { |