| ... | @@ -4671,22 +4671,6 @@ const GenericCallAdapter = struct { | ... | @@ -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 | fn analyzeCall( | 4674 | fn analyzeCall( |
| 4691 | sema: *Sema, | 4675 | sema: *Sema, |
| 4692 | block: *Block, | 4676 | block: *Block, |
| ... | @@ -5200,15 +5184,15 @@ fn instantiateGenericCall( | ... | @@ -5200,15 +5184,15 @@ fn instantiateGenericCall( |
| 5200 | .comptime_tvs = comptime_tvs, | 5184 | .comptime_tvs = comptime_tvs, |
| 5201 | .target = target, | 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 | const callee = if (!gop.found_existing) callee: { | 5188 | const callee = if (!gop.found_existing) callee: { |
| 5205 | const new_module_func = try gpa.create(Module.Fn); | 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 | gop.key_ptr.* = new_module_func; | 5193 | gop.key_ptr.* = new_module_func; |
| 5207 | errdefer gpa.destroy(new_module_func); | 5194 | errdefer gpa.destroy(new_module_func); |
| 5208 | const remove_adapter: GenericRemoveAdapter = .{ | 5195 | errdefer assert(mod.monomorphed_funcs.remove(new_module_func)); |
| 5209 | .precomputed_hash = precomputed_hash, | | |
| 5210 | }; | | |
| 5211 | errdefer assert(mod.monomorphed_funcs.removeAdapted(new_module_func, remove_adapter)); | | |
| 5212 | | 5196 | |
| 5213 | try namespace.anon_decls.ensureUnusedCapacity(gpa, 1); | 5197 | try namespace.anon_decls.ensureUnusedCapacity(gpa, 1); |
| 5214 | | 5198 | |
| ... | @@ -6494,12 +6478,14 @@ fn funcCommon( | ... | @@ -6494,12 +6478,14 @@ fn funcCommon( |
| 6494 | param_name.* = try sema.gpa.dupeZ(u8, block.params.items[i].name); | 6478 | param_name.* = try sema.gpa.dupeZ(u8, block.params.items[i].name); |
| 6495 | } | 6479 | } |
| 6496 | | 6480 | |
| | 6481 | const hash = new_func.hash; |
| 6497 | const fn_payload = try sema.arena.create(Value.Payload.Function); | 6482 | const fn_payload = try sema.arena.create(Value.Payload.Function); |
| 6498 | new_func.* = .{ | 6483 | new_func.* = .{ |
| 6499 | .state = anal_state, | 6484 | .state = anal_state, |
| 6500 | .zir_body_inst = func_inst, | 6485 | .zir_body_inst = func_inst, |
| 6501 | .owner_decl = sema.owner_decl, | 6486 | .owner_decl = sema.owner_decl, |
| 6502 | .comptime_args = comptime_args, | 6487 | .comptime_args = comptime_args, |
| | 6488 | .hash = hash, |
| 6503 | .lbrace_line = src_locs.lbrace_line, | 6489 | .lbrace_line = src_locs.lbrace_line, |
| 6504 | .rbrace_line = src_locs.rbrace_line, | 6490 | .rbrace_line = src_locs.rbrace_line, |
| 6505 | .lbrace_column = @truncate(u16, src_locs.columns), | 6491 | .lbrace_column = @truncate(u16, src_locs.columns), |
| ... | @@ -19987,18 +19973,39 @@ fn analyzeIsNonErr( | ... | @@ -19987,18 +19973,39 @@ fn analyzeIsNonErr( |
| 19987 | if (ot == .ErrorSet) return Air.Inst.Ref.bool_false; | 19973 | if (ot == .ErrorSet) return Air.Inst.Ref.bool_false; |
| 19988 | assert(ot == .ErrorUnion); | 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 | // exception if the error union error set is known to be empty, | 19985 | // exception if the error union error set is known to be empty, |
| 19991 | // we allow the comparison but always make it comptime known. | 19986 | // we allow the comparison but always make it comptime known. |
| 19992 | const set_ty = operand_ty.errorUnionSet(); | 19987 | const set_ty = operand_ty.errorUnionSet(); |
| 19993 | switch (set_ty.tag()) { | 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 | else => if (set_ty.errorSetNames().len == 0) return Air.Inst.Ref.bool_true, | 20003 | else => if (set_ty.errorSetNames().len == 0) return Air.Inst.Ref.bool_true, |
| 19996 | } | 20004 | } |
| 19997 | | 20005 | |
| 19998 | const result_ty = Type.bool; | 20006 | if (maybe_operand_val) |err_union| { |
| 19999 | if (try sema.resolveMaybeUndefVal(block, src, operand)) |err_union| { | | |
| 20000 | if (err_union.isUndef()) { | 20007 | if (err_union.isUndef()) { |
| 20001 | return sema.addConstUndef(result_ty); | 20008 | return sema.addConstUndef(Type.bool); |
| 20002 | } | 20009 | } |
| 20003 | if (err_union.getError() == null) { | 20010 | if (err_union.getError() == null) { |
| 20004 | return Air.Inst.Ref.bool_true; | 20011 | return Air.Inst.Ref.bool_true; |
| ... | @@ -20583,6 +20590,7 @@ fn wrapErrorUnionPayload( | ... | @@ -20583,6 +20590,7 @@ fn wrapErrorUnionPayload( |
| 20583 | return sema.addConstant(dest_ty, try Value.Tag.eu_payload.create(sema.arena, val)); | 20590 | return sema.addConstant(dest_ty, try Value.Tag.eu_payload.create(sema.arena, val)); |
| 20584 | } | 20591 | } |
| 20585 | try sema.requireRuntimeBlock(block, inst_src); | 20592 | try sema.requireRuntimeBlock(block, inst_src); |
| | 20593 | try sema.queueFullTypeResolution(dest_payload_ty); |
| 20586 | return block.addTyOp(.wrap_errunion_payload, dest_ty, coerced); | 20594 | return block.addTyOp(.wrap_errunion_payload, dest_ty, coerced); |
| 20587 | } | 20595 | } |
| 20588 | | 20596 | |
| ... | @@ -21372,6 +21380,9 @@ fn resolveStructFully( | ... | @@ -21372,6 +21380,9 @@ fn resolveStructFully( |
| 21372 | try sema.resolveTypeFully(block, src, field.ty); | 21380 | try sema.resolveTypeFully(block, src, field.ty); |
| 21373 | } | 21381 | } |
| 21374 | struct_obj.status = .fully_resolved; | 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 | fn resolveUnionFully( | 21388 | fn resolveUnionFully( |
| ... | @@ -21395,6 +21406,9 @@ fn resolveUnionFully( | ... | @@ -21395,6 +21406,9 @@ fn resolveUnionFully( |
| 21395 | try sema.resolveTypeFully(block, src, field.ty); | 21406 | try sema.resolveTypeFully(block, src, field.ty); |
| 21396 | } | 21407 | } |
| 21397 | union_obj.status = .fully_resolved; | 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 | pub fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!Type { | 21414 | pub fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!Type { |