| ... | ... | @@ -2507,6 +2507,11 @@ pub fn fail( |
| 2507 | 2507 | args: anytype, |
| 2508 | 2508 | ) CompileError { |
| 2509 | 2509 | const err_msg = try sema.errMsg(block, src, format, args); |
| 2510 | inline for (args) |arg| { |
| 2511 | if (@TypeOf(arg) == Type.Formatter) { |
| 2512 | try addDeclaredHereNote(sema, err_msg, arg.data.ty); |
| 2513 | } |
| 2514 | } |
| 2510 | 2515 | return sema.failWithOwnedErrorMsg(block, err_msg); |
| 2511 | 2516 | } |
| 2512 | 2517 | |
| ... | ... | @@ -5341,24 +5346,15 @@ fn failWithBadMemberAccess( |
| 5341 | 5346 | .Enum => "enum", |
| 5342 | 5347 | else => unreachable, |
| 5343 | 5348 | }; |
| 5344 | | const msg = msg: { |
| 5345 | | const msg = blk: { |
| 5346 | | if (agg_ty.getOwnerDeclOrNull(mod)) |some| if (mod.declIsRoot(some)) { |
| 5347 | | break :blk try sema.errMsg(block, field_src, "root struct of file '{}' has no member named '{}'", .{ |
| 5348 | | agg_ty.fmt(mod), field_name.fmt(&mod.intern_pool), |
| 5349 | | }); |
| 5350 | | }; |
| 5351 | | |
| 5352 | | break :blk try sema.errMsg(block, field_src, "{s} '{}' has no member named '{}'", .{ |
| 5353 | | kw_name, agg_ty.fmt(mod), field_name.fmt(&mod.intern_pool), |
| 5354 | | }); |
| 5355 | | }; |
| 5356 | | |
| 5357 | | errdefer msg.destroy(sema.gpa); |
| 5358 | | try sema.addDeclaredHereNote(msg, agg_ty); |
| 5359 | | break :msg msg; |
| 5349 | if (agg_ty.getOwnerDeclOrNull(mod)) |some| if (mod.declIsRoot(some)) { |
| 5350 | return sema.fail(block, field_src, "root struct of file '{}' has no member named '{}'", .{ |
| 5351 | agg_ty.fmt(mod), field_name.fmt(&mod.intern_pool), |
| 5352 | }); |
| 5360 | 5353 | }; |
| 5361 | | return sema.failWithOwnedErrorMsg(block, msg); |
| 5354 | |
| 5355 | return sema.fail(block, field_src, "{s} '{}' has no member named '{}'", .{ |
| 5356 | kw_name, agg_ty.fmt(mod), field_name.fmt(&mod.intern_pool), |
| 5357 | }); |
| 5362 | 5358 | } |
| 5363 | 5359 | |
| 5364 | 5360 | fn failWithBadStructFieldAccess( |
| ... | ... | @@ -8689,35 +8685,17 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8689 | 8685 | if (try sema.intFitsInType(int_val, int_tag_ty, null)) { |
| 8690 | 8686 | return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern()); |
| 8691 | 8687 | } |
| 8692 | | const msg = msg: { |
| 8693 | | const msg = try sema.errMsg( |
| 8694 | | block, |
| 8695 | | src, |
| 8696 | | "int value '{}' out of range of non-exhaustive enum '{}'", |
| 8697 | | .{ int_val.fmtValue(sema.typeOf(operand), mod), dest_ty.fmt(mod) }, |
| 8698 | | ); |
| 8699 | | errdefer msg.destroy(sema.gpa); |
| 8700 | | try sema.addDeclaredHereNote(msg, dest_ty); |
| 8701 | | break :msg msg; |
| 8702 | | }; |
| 8703 | | return sema.failWithOwnedErrorMsg(block, msg); |
| 8688 | return sema.fail(block, src, "int value '{}' out of range of non-exhaustive enum '{}'", .{ |
| 8689 | int_val.fmtValue(sema.typeOf(operand), mod), dest_ty.fmt(mod), |
| 8690 | }); |
| 8704 | 8691 | } |
| 8705 | 8692 | if (int_val.isUndef(mod)) { |
| 8706 | 8693 | return sema.failWithUseOfUndef(block, operand_src); |
| 8707 | 8694 | } |
| 8708 | 8695 | if (!(try sema.enumHasInt(dest_ty, int_val))) { |
| 8709 | | const msg = msg: { |
| 8710 | | const msg = try sema.errMsg( |
| 8711 | | block, |
| 8712 | | src, |
| 8713 | | "enum '{}' has no tag with value '{}'", |
| 8714 | | .{ dest_ty.fmt(mod), int_val.fmtValue(sema.typeOf(operand), mod) }, |
| 8715 | | ); |
| 8716 | | errdefer msg.destroy(sema.gpa); |
| 8717 | | try sema.addDeclaredHereNote(msg, dest_ty); |
| 8718 | | break :msg msg; |
| 8719 | | }; |
| 8720 | | return sema.failWithOwnedErrorMsg(block, msg); |
| 8696 | return sema.fail(block, src, "enum '{}' has no tag with value '{}'", .{ |
| 8697 | dest_ty.fmt(mod), int_val.fmtValue(sema.typeOf(operand), mod), |
| 8698 | }); |
| 8721 | 8699 | } |
| 8722 | 8700 | return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern()); |
| 8723 | 8701 | } |
| ... | ... | @@ -9401,16 +9379,9 @@ fn funcCommon( |
| 9401 | 9379 | } |
| 9402 | 9380 | if (!param_ty.isValidParamType(mod)) { |
| 9403 | 9381 | const opaque_str = if (param_ty.zigTypeTag(mod) == .Opaque) "opaque " else ""; |
| 9404 | | const msg = msg: { |
| 9405 | | const msg = try sema.errMsg(block, param_src, "parameter of {s}type '{}' not allowed", .{ |
| 9406 | | opaque_str, param_ty.fmt(mod), |
| 9407 | | }); |
| 9408 | | errdefer msg.destroy(sema.gpa); |
| 9409 | | |
| 9410 | | try sema.addDeclaredHereNote(msg, param_ty); |
| 9411 | | break :msg msg; |
| 9412 | | }; |
| 9413 | | return sema.failWithOwnedErrorMsg(block, msg); |
| 9382 | return sema.fail(block, param_src, "parameter of {s}type '{}' not allowed", .{ |
| 9383 | opaque_str, param_ty.fmt(mod), |
| 9384 | }); |
| 9414 | 9385 | } |
| 9415 | 9386 | if (!this_generic and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved) and !try sema.validateExternType(param_ty, .param_ty)) { |
| 9416 | 9387 | const msg = msg: { |
| ... | ... | @@ -9690,16 +9661,9 @@ fn finishFunc( |
| 9690 | 9661 | |
| 9691 | 9662 | if (!return_type.isValidReturnType(mod)) { |
| 9692 | 9663 | const opaque_str = if (return_type.zigTypeTag(mod) == .Opaque) "opaque " else ""; |
| 9693 | | const msg = msg: { |
| 9694 | | const msg = try sema.errMsg(block, ret_ty_src, "{s}return type '{}' not allowed", .{ |
| 9695 | | opaque_str, return_type.fmt(mod), |
| 9696 | | }); |
| 9697 | | errdefer msg.destroy(gpa); |
| 9698 | | |
| 9699 | | try sema.addDeclaredHereNote(msg, return_type); |
| 9700 | | break :msg msg; |
| 9701 | | }; |
| 9702 | | return sema.failWithOwnedErrorMsg(block, msg); |
| 9664 | return sema.fail(block, ret_ty_src, "{s}return type '{}' not allowed", .{ |
| 9665 | opaque_str, return_type.fmt(mod), |
| 9666 | }); |
| 9703 | 9667 | } |
| 9704 | 9668 | if (!ret_poison and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved) and |
| 9705 | 9669 | !try sema.validateExternType(return_type, .ret_ty)) |
| ... | ... | @@ -10848,15 +10812,9 @@ const SwitchProngAnalysis = struct { |
| 10848 | 10812 | else => unreachable, |
| 10849 | 10813 | }; |
| 10850 | 10814 | const capture_src = raw_tag_capture_src.resolve(mod, mod.declPtr(block.src_decl), switch_node_offset, .none); |
| 10851 | | const msg = msg: { |
| 10852 | | const msg = try sema.errMsg(block, capture_src, "cannot capture tag of non-union type '{}'", .{ |
| 10853 | | operand_ty.fmt(mod), |
| 10854 | | }); |
| 10855 | | errdefer msg.destroy(sema.gpa); |
| 10856 | | try sema.addDeclaredHereNote(msg, operand_ty); |
| 10857 | | break :msg msg; |
| 10858 | | }; |
| 10859 | | return sema.failWithOwnedErrorMsg(block, msg); |
| 10815 | return sema.fail(block, capture_src, "cannot capture tag of non-union type '{}'", .{ |
| 10816 | operand_ty.fmt(mod), |
| 10817 | }); |
| 10860 | 10818 | } |
| 10861 | 10819 | assert(inline_case_capture != .none); |
| 10862 | 10820 | return inline_case_capture; |
| ... | ... | @@ -19824,13 +19782,7 @@ fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 19824 | 19782 | const extra = sema.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data; |
| 19825 | 19783 | const union_ty = try sema.resolveType(block, ty_src, extra.union_type); |
| 19826 | 19784 | if (union_ty.zigTypeTag(sema.mod) != .Union) { |
| 19827 | | const msg = msg: { |
| 19828 | | const msg = try sema.errMsg(block, ty_src, "expected union type, found '{}'", .{union_ty.fmt(sema.mod)}); |
| 19829 | | errdefer msg.destroy(sema.gpa); |
| 19830 | | try sema.addDeclaredHereNote(msg, union_ty); |
| 19831 | | break :msg msg; |
| 19832 | | }; |
| 19833 | | return sema.failWithOwnedErrorMsg(block, msg); |
| 19785 | return sema.fail(block, ty_src, "expected union type, found '{}'", .{union_ty.fmt(sema.mod)}); |
| 19834 | 19786 | } |
| 19835 | 19787 | const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, .{ |
| 19836 | 19788 | .needed_comptime_reason = "name of field being initialized must be comptime-known", |
| ... | ... | @@ -20941,17 +20893,8 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 20941 | 20893 | return sema.addStrLit(ip.stringToSlice(tag_name)); |
| 20942 | 20894 | }, |
| 20943 | 20895 | .Enum => operand_ty, |
| 20944 | | .Union => operand_ty.unionTagType(mod) orelse { |
| 20945 | | const msg = msg: { |
| 20946 | | const msg = try sema.errMsg(block, src, "union '{}' is untagged", .{ |
| 20947 | | operand_ty.fmt(sema.mod), |
| 20948 | | }); |
| 20949 | | errdefer msg.destroy(sema.gpa); |
| 20950 | | try sema.addDeclaredHereNote(msg, operand_ty); |
| 20951 | | break :msg msg; |
| 20952 | | }; |
| 20953 | | return sema.failWithOwnedErrorMsg(block, msg); |
| 20954 | | }, |
| 20896 | .Union => operand_ty.unionTagType(mod) orelse |
| 20897 | return sema.fail(block, src, "union '{}' is untagged", .{operand_ty.fmt(sema.mod)}), |
| 20955 | 20898 | else => return sema.fail(block, operand_src, "expected enum or union; found '{}'", .{ |
| 20956 | 20899 | operand_ty.fmt(mod), |
| 20957 | 20900 | }), |
| ... | ... | @@ -21567,16 +21510,9 @@ fn zirReify( |
| 21567 | 21510 | if (enum_tag_ty != .none) { |
| 21568 | 21511 | const tag_info = ip.indexToKey(enum_tag_ty).enum_type; |
| 21569 | 21512 | const enum_index = tag_info.nameIndex(ip, field_name) orelse { |
| 21570 | | const msg = msg: { |
| 21571 | | const msg = try sema.errMsg(block, src, "no field named '{}' in enum '{}'", .{ |
| 21572 | | field_name.fmt(ip), |
| 21573 | | Type.fromInterned(enum_tag_ty).fmt(mod), |
| 21574 | | }); |
| 21575 | | errdefer msg.destroy(gpa); |
| 21576 | | try sema.addDeclaredHereNote(msg, Type.fromInterned(enum_tag_ty)); |
| 21577 | | break :msg msg; |
| 21578 | | }; |
| 21579 | | return sema.failWithOwnedErrorMsg(block, msg); |
| 21513 | return sema.fail(block, src, "no field named '{}' in enum '{}'", .{ |
| 21514 | field_name.fmt(ip), Type.fromInterned(enum_tag_ty).fmt(mod), |
| 21515 | }); |
| 21580 | 21516 | }; |
| 21581 | 21517 | assert(explicit_tags_seen.len == tag_info.names.len); |
| 21582 | 21518 | // No check for duplicate because the check already happened in order |
| ... | ... | @@ -22447,19 +22383,9 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData |
| 22447 | 22383 | break :disjoint true; |
| 22448 | 22384 | }; |
| 22449 | 22385 | if (disjoint and dest_tag != .ErrorUnion) { |
| 22450 | | const msg = msg: { |
| 22451 | | const msg = try sema.errMsg( |
| 22452 | | block, |
| 22453 | | src, |
| 22454 | | "error sets '{}' and '{}' have no common errors", |
| 22455 | | .{ operand_ty.fmt(sema.mod), dest_ty.fmt(sema.mod) }, |
| 22456 | | ); |
| 22457 | | errdefer msg.destroy(sema.gpa); |
| 22458 | | try sema.addDeclaredHereNote(msg, operand_ty); |
| 22459 | | try sema.addDeclaredHereNote(msg, dest_ty); |
| 22460 | | break :msg msg; |
| 22461 | | }; |
| 22462 | | return sema.failWithOwnedErrorMsg(block, msg); |
| 22386 | return sema.fail(block, src, "error sets '{}' and '{}' have no common errors", .{ |
| 22387 | operand_ty.fmt(sema.mod), dest_ty.fmt(sema.mod), |
| 22388 | }); |
| 22463 | 22389 | } |
| 22464 | 22390 | |
| 22465 | 22391 | if (maybe_operand_val) |val| { |
| ... | ... | @@ -22473,18 +22399,9 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData |
| 22473 | 22399 | error_name = operand_val.err.name; |
| 22474 | 22400 | } |
| 22475 | 22401 | if (!Type.errorSetHasFieldIp(ip, dest_ty.toIntern(), error_name)) { |
| 22476 | | const msg = msg: { |
| 22477 | | const msg = try sema.errMsg( |
| 22478 | | block, |
| 22479 | | src, |
| 22480 | | "'error.{}' not a member of error set '{}'", |
| 22481 | | .{ error_name.fmt(ip), dest_ty.fmt(sema.mod) }, |
| 22482 | | ); |
| 22483 | | errdefer msg.destroy(sema.gpa); |
| 22484 | | try sema.addDeclaredHereNote(msg, dest_ty); |
| 22485 | | break :msg msg; |
| 22486 | | }; |
| 22487 | | return sema.failWithOwnedErrorMsg(block, msg); |
| 22402 | return sema.fail(block, src, "'error.{}' not a member of error set '{}'", .{ |
| 22403 | error_name.fmt(ip), dest_ty.fmt(sema.mod), |
| 22404 | }); |
| 22488 | 22405 | } |
| 22489 | 22406 | } |
| 22490 | 22407 | |
| ... | ... | @@ -23257,15 +23174,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6 |
| 23257 | 23174 | try sema.resolveTypeLayout(ty); |
| 23258 | 23175 | switch (ty.zigTypeTag(mod)) { |
| 23259 | 23176 | .Struct => {}, |
| 23260 | | else => { |
| 23261 | | const msg = msg: { |
| 23262 | | const msg = try sema.errMsg(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(mod)}); |
| 23263 | | errdefer msg.destroy(sema.gpa); |
| 23264 | | try sema.addDeclaredHereNote(msg, ty); |
| 23265 | | break :msg msg; |
| 23266 | | }; |
| 23267 | | return sema.failWithOwnedErrorMsg(block, msg); |
| 23268 | | }, |
| 23177 | else => return sema.fail(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(mod)}), |
| 23269 | 23178 | } |
| 23270 | 23179 | |
| 23271 | 23180 | const field_index = if (ty.isTuple(mod)) blk: { |
| ... | ... | @@ -24708,23 +24617,9 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 24708 | 24617 | } orelse return sema.fail(block, ptr_src, "pointer value not based on parent struct", .{}); |
| 24709 | 24618 | |
| 24710 | 24619 | if (field.index != field_index) { |
| 24711 | | const msg = msg: { |
| 24712 | | const msg = try sema.errMsg( |
| 24713 | | block, |
| 24714 | | src, |
| 24715 | | "field '{}' has index '{d}' but pointer value is index '{d}' of struct '{}'", |
| 24716 | | .{ |
| 24717 | | field_name.fmt(ip), |
| 24718 | | field_index, |
| 24719 | | field.index, |
| 24720 | | parent_ty.fmt(sema.mod), |
| 24721 | | }, |
| 24722 | | ); |
| 24723 | | errdefer msg.destroy(sema.gpa); |
| 24724 | | try sema.addDeclaredHereNote(msg, parent_ty); |
| 24725 | | break :msg msg; |
| 24726 | | }; |
| 24727 | | return sema.failWithOwnedErrorMsg(block, msg); |
| 24620 | return sema.fail(block, src, "field '{}' has index '{d}' but pointer value is index '{d}' of struct '{}'", .{ |
| 24621 | field_name.fmt(ip), field_index, field.index, parent_ty.fmt(sema.mod), |
| 24622 | }); |
| 24728 | 24623 | } |
| 24729 | 24624 | return Air.internedToRef(field.base); |
| 24730 | 24625 | } |
| ... | ... | @@ -26916,15 +26811,9 @@ fn fieldVal( |
| 26916 | 26811 | switch (ip.indexToKey(child_type.toIntern())) { |
| 26917 | 26812 | .error_set_type => |error_set_type| blk: { |
| 26918 | 26813 | if (error_set_type.nameIndex(ip, field_name) != null) break :blk; |
| 26919 | | const msg = msg: { |
| 26920 | | const msg = try sema.errMsg(block, src, "no error named '{}' in '{}'", .{ |
| 26921 | | field_name.fmt(ip), child_type.fmt(mod), |
| 26922 | | }); |
| 26923 | | errdefer msg.destroy(sema.gpa); |
| 26924 | | try sema.addDeclaredHereNote(msg, child_type); |
| 26925 | | break :msg msg; |
| 26926 | | }; |
| 26927 | | return sema.failWithOwnedErrorMsg(block, msg); |
| 26814 | return sema.fail(block, src, "no error named '{}' in '{}'", .{ |
| 26815 | field_name.fmt(ip), child_type.fmt(mod), |
| 26816 | }); |
| 26928 | 26817 | }, |
| 26929 | 26818 | .inferred_error_set_type => { |
| 26930 | 26819 | return sema.fail(block, src, "TODO handle inferred error sets here", .{}); |
| ... | ... | @@ -29072,18 +28961,9 @@ fn coerceExtra( |
| 29072 | 28961 | const val = try sema.resolveConstDefinedValue(block, .unneeded, inst, undefined); |
| 29073 | 28962 | const string = mod.intern_pool.indexToKey(val.toIntern()).enum_literal; |
| 29074 | 28963 | const field_index = dest_ty.enumFieldIndex(string, mod) orelse { |
| 29075 | | const msg = msg: { |
| 29076 | | const msg = try sema.errMsg( |
| 29077 | | block, |
| 29078 | | inst_src, |
| 29079 | | "no field named '{}' in enum '{}'", |
| 29080 | | .{ string.fmt(&mod.intern_pool), dest_ty.fmt(mod) }, |
| 29081 | | ); |
| 29082 | | errdefer msg.destroy(sema.gpa); |
| 29083 | | try sema.addDeclaredHereNote(msg, dest_ty); |
| 29084 | | break :msg msg; |
| 29085 | | }; |
| 29086 | | return sema.failWithOwnedErrorMsg(block, msg); |
| 28964 | return sema.fail(block, inst_src, "no field named '{}' in enum '{}'", .{ |
| 28965 | string.fmt(&mod.intern_pool), dest_ty.fmt(mod), |
| 28966 | }); |
| 29087 | 28967 | }; |
| 29088 | 28968 | return Air.internedToRef((try mod.enumValueFieldIndex(dest_ty, @intCast(field_index))).toIntern()); |
| 29089 | 28969 | }, |
| ... | ... | @@ -31718,15 +31598,9 @@ fn coerceEnumToUnion( |
| 31718 | 31598 | const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src); |
| 31719 | 31599 | if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| { |
| 31720 | 31600 | const field_index = union_ty.unionTagFieldIndex(val, sema.mod) orelse { |
| 31721 | | const msg = msg: { |
| 31722 | | const msg = try sema.errMsg(block, inst_src, "union '{}' has no tag with value '{}'", .{ |
| 31723 | | union_ty.fmt(sema.mod), val.fmtValue(tag_ty, sema.mod), |
| 31724 | | }); |
| 31725 | | errdefer msg.destroy(sema.gpa); |
| 31726 | | try sema.addDeclaredHereNote(msg, union_ty); |
| 31727 | | break :msg msg; |
| 31728 | | }; |
| 31729 | | return sema.failWithOwnedErrorMsg(block, msg); |
| 31601 | return sema.fail(block, inst_src, "union '{}' has no tag with value '{}'", .{ |
| 31602 | union_ty.fmt(sema.mod), val.fmtValue(tag_ty, sema.mod), |
| 31603 | }); |
| 31730 | 31604 | }; |
| 31731 | 31605 | |
| 31732 | 31606 | const union_obj = mod.typeToUnion(union_ty).?; |
| ... | ... | @@ -37202,19 +37076,13 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un |
| 37202 | 37076 | if (explicit_tags_seen.len > 0) { |
| 37203 | 37077 | const tag_info = ip.indexToKey(union_type.tagTypePtr(ip).*).enum_type; |
| 37204 | 37078 | const enum_index = tag_info.nameIndex(ip, field_name) orelse { |
| 37205 | | const msg = msg: { |
| 37206 | | const ty_src = mod.fieldSrcLoc(union_type.decl, .{ |
| 37207 | | .index = field_i, |
| 37208 | | .range = .name, |
| 37209 | | }).lazy; |
| 37210 | | const msg = try sema.errMsg(&block_scope, ty_src, "no field named '{}' in enum '{}'", .{ |
| 37211 | | field_name.fmt(ip), Type.fromInterned(union_type.tagTypePtr(ip).*).fmt(mod), |
| 37212 | | }); |
| 37213 | | errdefer msg.destroy(sema.gpa); |
| 37214 | | try sema.addDeclaredHereNote(msg, Type.fromInterned(union_type.tagTypePtr(ip).*)); |
| 37215 | | break :msg msg; |
| 37216 | | }; |
| 37217 | | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| 37079 | const ty_src = mod.fieldSrcLoc(union_type.decl, .{ |
| 37080 | .index = field_i, |
| 37081 | .range = .name, |
| 37082 | }).lazy; |
| 37083 | return sema.fail(&block_scope, ty_src, "no field named '{}' in enum '{}'", .{ |
| 37084 | field_name.fmt(ip), Type.fromInterned(union_type.tagTypePtr(ip).*).fmt(mod), |
| 37085 | }); |
| 37218 | 37086 | }; |
| 37219 | 37087 | |
| 37220 | 37088 | // No check for duplicate because the check already happened in order |