| ... | ... | @@ -23069,7 +23069,7 @@ fn analyzeMinMax( |
| 23069 | 23069 | if (std.debug.runtime_safety) { |
| 23070 | 23070 | assert(try sema.intFitsInType(val, refined_ty, null)); |
| 23071 | 23071 | } |
| 23072 | | cur_minmax = try sema.coerceInMemory(block, val, orig_ty, refined_ty, src); |
| 23072 | cur_minmax = try sema.coerceInMemory(val, refined_ty); |
| 23073 | 23073 | } |
| 23074 | 23074 | |
| 23075 | 23075 | break :refined refined_ty; |
| ... | ... | @@ -26610,7 +26610,7 @@ fn coerceExtra( |
| 26610 | 26610 | var in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src); |
| 26611 | 26611 | if (in_memory_result == .ok) { |
| 26612 | 26612 | if (maybe_inst_val) |val| { |
| 26613 | | return sema.coerceInMemory(block, val, inst_ty, dest_ty, dest_ty_src); |
| 26613 | return sema.coerceInMemory(val, dest_ty); |
| 26614 | 26614 | } |
| 26615 | 26615 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 26616 | 26616 | return block.addBitCast(dest_ty, inst); |
| ... | ... | @@ -27278,89 +27278,12 @@ fn coerceExtra( |
| 27278 | 27278 | return sema.failWithOwnedErrorMsg(msg); |
| 27279 | 27279 | } |
| 27280 | 27280 | |
| 27281 | | fn coerceValueInMemory( |
| 27282 | | sema: *Sema, |
| 27283 | | block: *Block, |
| 27284 | | val: Value, |
| 27285 | | src_ty: Type, |
| 27286 | | dst_ty: Type, |
| 27287 | | dst_ty_src: LazySrcLoc, |
| 27288 | | ) CompileError!Value { |
| 27289 | | const mod = sema.mod; |
| 27290 | | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 27291 | | .aggregate => |aggregate| { |
| 27292 | | const dst_ty_key = mod.intern_pool.indexToKey(dst_ty.toIntern()); |
| 27293 | | const dest_len = try sema.usizeCast( |
| 27294 | | block, |
| 27295 | | dst_ty_src, |
| 27296 | | mod.intern_pool.aggregateTypeLen(dst_ty.toIntern()), |
| 27297 | | ); |
| 27298 | | direct: { |
| 27299 | | const src_ty_child = switch (mod.intern_pool.indexToKey(src_ty.toIntern())) { |
| 27300 | | inline .array_type, .vector_type => |seq_type| seq_type.child, |
| 27301 | | .anon_struct_type, .struct_type => break :direct, |
| 27302 | | else => unreachable, |
| 27303 | | }; |
| 27304 | | const dst_ty_child = switch (dst_ty_key) { |
| 27305 | | inline .array_type, .vector_type => |seq_type| seq_type.child, |
| 27306 | | .anon_struct_type, .struct_type => break :direct, |
| 27307 | | else => unreachable, |
| 27308 | | }; |
| 27309 | | if (src_ty_child != dst_ty_child) break :direct; |
| 27310 | | // TODO: write something like getCoercedInts to avoid needing to dupe |
| 27311 | | return (try mod.intern(.{ .aggregate = .{ |
| 27312 | | .ty = dst_ty.toIntern(), |
| 27313 | | .storage = switch (aggregate.storage) { |
| 27314 | | .bytes => |bytes| .{ .bytes = try sema.arena.dupe(u8, bytes[0..dest_len]) }, |
| 27315 | | .elems => |elems| .{ .elems = try sema.arena.dupe(InternPool.Index, elems[0..dest_len]) }, |
| 27316 | | .repeated_elem => |elem| .{ .repeated_elem = elem }, |
| 27317 | | }, |
| 27318 | | } })).toValue(); |
| 27319 | | } |
| 27320 | | const dest_elems = try sema.arena.alloc(InternPool.Index, dest_len); |
| 27321 | | for (dest_elems, 0..) |*dest_elem, i| { |
| 27322 | | const elem_ty = switch (dst_ty_key) { |
| 27323 | | inline .array_type, .vector_type => |seq_type| seq_type.child, |
| 27324 | | .anon_struct_type => |anon_struct_type| anon_struct_type.types[i], |
| 27325 | | .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).? |
| 27326 | | .fields.values()[i].ty.toIntern(), |
| 27327 | | else => unreachable, |
| 27328 | | }; |
| 27329 | | const cur_val = switch (aggregate.storage) { |
| 27330 | | .bytes => |bytes| (try mod.intValue(Type.u8, bytes[i])).toIntern(), |
| 27331 | | .elems => |elems| elems[i], |
| 27332 | | .repeated_elem => |elem| elem, |
| 27333 | | }; |
| 27334 | | dest_elem.* = (try sema.coerceValueInMemory( |
| 27335 | | block, |
| 27336 | | cur_val.toValue(), |
| 27337 | | mod.intern_pool.typeOf(cur_val).toType(), |
| 27338 | | elem_ty.toType(), |
| 27339 | | dst_ty_src, |
| 27340 | | )).toIntern(); |
| 27341 | | } |
| 27342 | | return (try mod.intern(.{ .aggregate = .{ |
| 27343 | | .ty = dst_ty.toIntern(), |
| 27344 | | .storage = .{ .elems = dest_elems }, |
| 27345 | | } })).toValue(); |
| 27346 | | }, |
| 27347 | | .float => |float| (try mod.intern(.{ .float = .{ |
| 27348 | | .ty = dst_ty.toIntern(), |
| 27349 | | .storage = float.storage, |
| 27350 | | } })).toValue(), |
| 27351 | | else => try mod.getCoerced(val, dst_ty), |
| 27352 | | }; |
| 27353 | | } |
| 27354 | | |
| 27355 | 27281 | fn coerceInMemory( |
| 27356 | 27282 | sema: *Sema, |
| 27357 | | block: *Block, |
| 27358 | 27283 | val: Value, |
| 27359 | | src_ty: Type, |
| 27360 | 27284 | dst_ty: Type, |
| 27361 | | dst_ty_src: LazySrcLoc, |
| 27362 | 27285 | ) CompileError!Air.Inst.Ref { |
| 27363 | | return sema.addConstant(dst_ty, try sema.coerceValueInMemory(block, val, src_ty, dst_ty, dst_ty_src)); |
| 27286 | return sema.addConstant(dst_ty, try sema.mod.getCoerced(val, dst_ty)); |
| 27364 | 27287 | } |
| 27365 | 27288 | |
| 27366 | 27289 | const InMemoryCoercionResult = union(enum) { |
| ... | ... | @@ -29820,7 +29743,7 @@ fn coerceArrayLike( |
| 29820 | 29743 | if (in_memory_result == .ok) { |
| 29821 | 29744 | if (try sema.resolveMaybeUndefVal(inst)) |inst_val| { |
| 29822 | 29745 | // These types share the same comptime value representation. |
| 29823 | | return sema.coerceInMemory(block, inst_val, inst_ty, dest_ty, dest_ty_src); |
| 29746 | return sema.coerceInMemory(inst_val, dest_ty); |
| 29824 | 29747 | } |
| 29825 | 29748 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 29826 | 29749 | return block.addBitCast(dest_ty, inst); |
| ... | ... | @@ -31653,40 +31576,12 @@ const PeerResolveStrategy = enum { |
| 31653 | 31576 | /// The peers must all be of the same type. |
| 31654 | 31577 | exact, |
| 31655 | 31578 | |
| 31656 | | const Reason = struct { |
| 31657 | | peers: std.DynamicBitSet, |
| 31658 | | fn reset(r: *Reason) void { |
| 31659 | | r.peers.setRangeValue(.{ .start = 0, .end = r.peers.capacity() }, false); |
| 31660 | | } |
| 31661 | | }; |
| 31662 | | |
| 31663 | | fn name(s: PeerResolveStrategy) []const u8 { |
| 31664 | | return switch (s) { |
| 31665 | | .unknown, .exact => "exact", |
| 31666 | | .error_set => "error set", |
| 31667 | | .error_union => "error union", |
| 31668 | | .nullable => "null", |
| 31669 | | .optional => "optional", |
| 31670 | | .array => "array", |
| 31671 | | .vector => "vector", |
| 31672 | | .c_ptr => "C pointer", |
| 31673 | | .ptr => "pointer", |
| 31674 | | .func => "function", |
| 31675 | | .enum_or_union => "enum or union", |
| 31676 | | .comptime_int => "comptime_int", |
| 31677 | | .comptime_float => "comptime_float", |
| 31678 | | .fixed_int => "fixed-width int", |
| 31679 | | .fixed_float => "fixed-width float", |
| 31680 | | .coercible_struct => "anonymous struct or tuple", |
| 31681 | | }; |
| 31682 | | } |
| 31683 | | |
| 31684 | 31579 | /// Given two strategies, find a strategy that satisfies both, if one exists. If no such |
| 31685 | 31580 | /// strategy exists, any strategy may be returned; an error will be emitted when the caller |
| 31686 | 31581 | /// attempts to use the strategy to resolve the type. |
| 31687 | | /// Strategy `a` comes from the peers set in `reason`, while strategy `b` comes from the peer at |
| 31688 | | /// index `b_peer_idx`. `reason` will be updated to reflect the reason for the new strategy. |
| 31689 | | fn merge(a: PeerResolveStrategy, b: PeerResolveStrategy, reason: *Reason, b_peer_idx: usize) PeerResolveStrategy { |
| 31582 | /// Strategy `a` comes from the peer in `reason_peer`, while strategy `b` comes from the peer at |
| 31583 | /// index `b_peer_idx`. `reason_peer` is updated to reflect the reason for the new strategy. |
| 31584 | fn merge(a: PeerResolveStrategy, b: PeerResolveStrategy, reason_peer: *usize, b_peer_idx: usize) PeerResolveStrategy { |
| 31690 | 31585 | // Our merging should be order-independent. Thus, even though the union order is arbitrary, |
| 31691 | 31586 | // by sorting the tags and switching first on the smaller, we have half as many cases to |
| 31692 | 31587 | // worry about (since we avoid the duplicates). |
| ... | ... | @@ -31698,14 +31593,13 @@ const PeerResolveStrategy = enum { |
| 31698 | 31593 | all_s0, |
| 31699 | 31594 | all_s1, |
| 31700 | 31595 | either, |
| 31701 | | both, |
| 31702 | 31596 | }; |
| 31703 | 31597 | |
| 31704 | 31598 | const res: struct { ReasonMethod, PeerResolveStrategy } = switch (s0) { |
| 31705 | 31599 | .unknown => .{ .all_s1, s1 }, |
| 31706 | 31600 | .error_set => switch (s1) { |
| 31707 | 31601 | .error_set => .{ .either, .error_set }, |
| 31708 | | else => .{ .both, .error_union }, |
| 31602 | else => .{ .all_s0, .error_union }, |
| 31709 | 31603 | }, |
| 31710 | 31604 | .error_union => switch (s1) { |
| 31711 | 31605 | .error_union => .{ .either, .error_union }, |
| ... | ... | @@ -31714,7 +31608,7 @@ const PeerResolveStrategy = enum { |
| 31714 | 31608 | .nullable => switch (s1) { |
| 31715 | 31609 | .nullable => .{ .either, .nullable }, |
| 31716 | 31610 | .c_ptr => .{ .all_s1, .c_ptr }, |
| 31717 | | else => .{ .both, .optional }, |
| 31611 | else => .{ .all_s0, .optional }, |
| 31718 | 31612 | }, |
| 31719 | 31613 | .optional => switch (s1) { |
| 31720 | 31614 | .optional => .{ .either, .optional }, |
| ... | ... | @@ -31772,23 +31666,17 @@ const PeerResolveStrategy = enum { |
| 31772 | 31666 | switch (res[0]) { |
| 31773 | 31667 | .all_s0 => { |
| 31774 | 31668 | if (!s0_is_a) { |
| 31775 | | reason.reset(); |
| 31776 | | reason.peers.set(b_peer_idx); |
| 31669 | reason_peer.* = b_peer_idx; |
| 31777 | 31670 | } |
| 31778 | 31671 | }, |
| 31779 | 31672 | .all_s1 => { |
| 31780 | 31673 | if (s0_is_a) { |
| 31781 | | reason.reset(); |
| 31782 | | reason.peers.set(b_peer_idx); |
| 31674 | reason_peer.* = b_peer_idx; |
| 31783 | 31675 | } |
| 31784 | 31676 | }, |
| 31785 | 31677 | .either => { |
| 31786 | | // Prefer b, since it's a single peer |
| 31787 | | reason.reset(); |
| 31788 | | reason.peers.set(b_peer_idx); |
| 31789 | | }, |
| 31790 | | .both => { |
| 31791 | | reason.peers.set(b_peer_idx); |
| 31678 | // Prefer the earliest peer |
| 31679 | reason_peer.* = @min(reason_peer.*, b_peer_idx); |
| 31792 | 31680 | }, |
| 31793 | 31681 | } |
| 31794 | 31682 | |
| ... | ... | @@ -31820,12 +31708,7 @@ const PeerResolveStrategy = enum { |
| 31820 | 31708 | const PeerResolveResult = union(enum) { |
| 31821 | 31709 | /// The peer type resolution was successful, and resulted in the given type. |
| 31822 | 31710 | success: Type, |
| 31823 | | /// The chosen strategy was incompatible with the given peer. |
| 31824 | | bad_strat: struct { |
| 31825 | | strat: PeerResolveStrategy, |
| 31826 | | peer_idx: usize, |
| 31827 | | }, |
| 31828 | | /// There was some conflict between two specific peers. |
| 31711 | /// There was some generic conflict between two peers. |
| 31829 | 31712 | conflict: struct { |
| 31830 | 31713 | peer_idx_a: usize, |
| 31831 | 31714 | peer_idx_b: usize, |
| ... | ... | @@ -31847,7 +31730,6 @@ const PeerResolveResult = union(enum) { |
| 31847 | 31730 | src: LazySrcLoc, |
| 31848 | 31731 | instructions: []const Air.Inst.Ref, |
| 31849 | 31732 | candidate_srcs: Module.PeerTypeCandidateSrc, |
| 31850 | | strat_reason: PeerResolveStrategy.Reason, |
| 31851 | 31733 | ) !*Module.ErrorMsg { |
| 31852 | 31734 | const mod = sema.mod; |
| 31853 | 31735 | const decl_ptr = mod.declPtr(block.src_decl); |
| ... | ... | @@ -31867,41 +31749,6 @@ const PeerResolveResult = union(enum) { |
| 31867 | 31749 | |
| 31868 | 31750 | switch (cur) { |
| 31869 | 31751 | .success => unreachable, |
| 31870 | | .bad_strat => |bad_strat| bad_strat: { |
| 31871 | | if (strat_reason.peers.count() == 1) { |
| 31872 | | // We can write this error more simply as a conflict between two peers |
| 31873 | | conflict_idx = .{ |
| 31874 | | strat_reason.peers.findFirstSet().?, |
| 31875 | | bad_strat.peer_idx, |
| 31876 | | }; |
| 31877 | | break :bad_strat; |
| 31878 | | } |
| 31879 | | |
| 31880 | | const fmt = "type resolution strategy failed"; |
| 31881 | | const msg = if (opt_msg) |msg| msg: { |
| 31882 | | try sema.errNote(block, src, msg, fmt, .{}); |
| 31883 | | break :msg msg; |
| 31884 | | } else msg: { |
| 31885 | | const msg = try sema.errMsg(block, src, fmt, .{}); |
| 31886 | | opt_msg = msg; |
| 31887 | | break :msg msg; |
| 31888 | | }; |
| 31889 | | |
| 31890 | | const peer_ty = peer_tys[bad_strat.peer_idx]; |
| 31891 | | const peer_src = candidate_srcs.resolve(mod, decl_ptr, bad_strat.peer_idx) orelse src; |
| 31892 | | try sema.errNote(block, peer_src, msg, "strategy '{s}' failed for type '{}' here", .{ bad_strat.strat.name(), peer_ty.fmt(mod) }); |
| 31893 | | |
| 31894 | | try sema.errNote(block, src, msg, "strategy chosen using {} peers", .{strat_reason.peers.count()}); |
| 31895 | | var it = strat_reason.peers.iterator(.{}); |
| 31896 | | while (it.next()) |strat_peer_idx| { |
| 31897 | | const strat_peer_ty = peer_tys[strat_peer_idx]; |
| 31898 | | const strat_peer_src = candidate_srcs.resolve(mod, decl_ptr, strat_peer_idx) orelse src; |
| 31899 | | try sema.errNote(block, strat_peer_src, msg, "peer of type '{}' here", .{strat_peer_ty.fmt(mod)}); |
| 31900 | | } |
| 31901 | | |
| 31902 | | // No child error |
| 31903 | | break; |
| 31904 | | }, |
| 31905 | 31752 | .conflict => |conflict| { |
| 31906 | 31753 | // Fall through to two-peer conflict handling below |
| 31907 | 31754 | conflict_idx = .{ |
| ... | ... | @@ -31925,7 +31772,7 @@ const PeerResolveResult = union(enum) { |
| 31925 | 31772 | }, |
| 31926 | 31773 | } |
| 31927 | 31774 | |
| 31928 | | // This is the path for reporting a conflict between two peers. |
| 31775 | // This is the path for reporting a generic conflict between two peers. |
| 31929 | 31776 | |
| 31930 | 31777 | if (conflict_idx[1] < conflict_idx[0]) { |
| 31931 | 31778 | // b comes first in source, so it's better if it comes first in the error |
| ... | ... | @@ -31987,14 +31834,10 @@ fn resolvePeerTypes( |
| 31987 | 31834 | val.* = try sema.resolveMaybeUndefVal(inst); |
| 31988 | 31835 | } |
| 31989 | 31836 | |
| 31990 | | var strat_reason: PeerResolveStrategy.Reason = .{ |
| 31991 | | .peers = try std.DynamicBitSet.initEmpty(sema.arena, instructions.len), |
| 31992 | | }; |
| 31993 | | |
| 31994 | | switch (try sema.resolvePeerTypesInner(block, src, peer_tys, peer_vals, &strat_reason)) { |
| 31837 | switch (try sema.resolvePeerTypesInner(block, src, peer_tys, peer_vals)) { |
| 31995 | 31838 | .success => |ty| return ty, |
| 31996 | 31839 | else => |result| { |
| 31997 | | const msg = try result.report(sema, block, src, instructions, candidate_srcs, strat_reason); |
| 31840 | const msg = try result.report(sema, block, src, instructions, candidate_srcs); |
| 31998 | 31841 | return sema.failWithOwnedErrorMsg(msg); |
| 31999 | 31842 | }, |
| 32000 | 31843 | } |
| ... | ... | @@ -32006,16 +31849,14 @@ fn resolvePeerTypesInner( |
| 32006 | 31849 | src: LazySrcLoc, |
| 32007 | 31850 | peer_tys: []?Type, |
| 32008 | 31851 | peer_vals: []?Value, |
| 32009 | | strat_reason: *PeerResolveStrategy.Reason, |
| 32010 | 31852 | ) !PeerResolveResult { |
| 32011 | 31853 | const mod = sema.mod; |
| 32012 | 31854 | |
| 32013 | | strat_reason.reset(); |
| 32014 | | |
| 31855 | var strat_reason: usize = 0; |
| 32015 | 31856 | var s: PeerResolveStrategy = .unknown; |
| 32016 | 31857 | for (peer_tys, 0..) |opt_ty, i| { |
| 32017 | 31858 | const ty = opt_ty orelse continue; |
| 32018 | | s = s.merge(PeerResolveStrategy.select(ty, mod), strat_reason, i); |
| 31859 | s = s.merge(PeerResolveStrategy.select(ty, mod), &strat_reason, i); |
| 32019 | 31860 | } |
| 32020 | 31861 | |
| 32021 | 31862 | if (s == .unknown) { |
| ... | ... | @@ -32041,9 +31882,9 @@ fn resolvePeerTypesInner( |
| 32041 | 31882 | var final_set: ?Type = null; |
| 32042 | 31883 | for (peer_tys, 0..) |opt_ty, i| { |
| 32043 | 31884 | const ty = opt_ty orelse continue; |
| 32044 | | if (ty.zigTypeTag(mod) != .ErrorSet) return .{ .bad_strat = .{ |
| 32045 | | .strat = s, |
| 32046 | | .peer_idx = i, |
| 31885 | if (ty.zigTypeTag(mod) != .ErrorSet) return .{ .conflict = .{ |
| 31886 | .peer_idx_a = strat_reason, |
| 31887 | .peer_idx_b = i, |
| 32047 | 31888 | } }; |
| 32048 | 31889 | if (final_set) |cur_set| { |
| 32049 | 31890 | final_set = try sema.maybeMergeErrorSets(block, src, cur_set, ty); |
| ... | ... | @@ -32091,7 +31932,6 @@ fn resolvePeerTypesInner( |
| 32091 | 31932 | src, |
| 32092 | 31933 | peer_tys, |
| 32093 | 31934 | peer_vals, |
| 32094 | | strat_reason, |
| 32095 | 31935 | )) { |
| 32096 | 31936 | .success => |ty| ty, |
| 32097 | 31937 | else => |result| return result, |
| ... | ... | @@ -32102,9 +31942,9 @@ fn resolvePeerTypesInner( |
| 32102 | 31942 | .nullable => { |
| 32103 | 31943 | for (peer_tys, 0..) |opt_ty, i| { |
| 32104 | 31944 | const ty = opt_ty orelse continue; |
| 32105 | | if (!ty.eql(Type.null, mod)) return .{ .bad_strat = .{ |
| 32106 | | .strat = s, |
| 32107 | | .peer_idx = i, |
| 31945 | if (!ty.eql(Type.null, mod)) return .{ .conflict = .{ |
| 31946 | .peer_idx_a = strat_reason, |
| 31947 | .peer_idx_b = i, |
| 32108 | 31948 | } }; |
| 32109 | 31949 | } |
| 32110 | 31950 | return .{ .success = Type.null }; |
| ... | ... | @@ -32130,7 +31970,6 @@ fn resolvePeerTypesInner( |
| 32130 | 31970 | src, |
| 32131 | 31971 | peer_tys, |
| 32132 | 31972 | peer_vals, |
| 32133 | | strat_reason, |
| 32134 | 31973 | )) { |
| 32135 | 31974 | .success => |ty| ty, |
| 32136 | 31975 | else => |result| return result, |
| ... | ... | @@ -32154,9 +31993,9 @@ fn resolvePeerTypesInner( |
| 32154 | 31993 | |
| 32155 | 31994 | if (!ty.isArrayOrVector(mod)) { |
| 32156 | 31995 | // We allow tuples of the correct length. We won't validate their elem type, since the elements can be coerced. |
| 32157 | | const arr_like = sema.typeIsArrayLike(ty) orelse return .{ .bad_strat = .{ |
| 32158 | | .strat = s, |
| 32159 | | .peer_idx = i, |
| 31996 | const arr_like = sema.typeIsArrayLike(ty) orelse return .{ .conflict = .{ |
| 31997 | .peer_idx_a = strat_reason, |
| 31998 | .peer_idx_b = i, |
| 32160 | 31999 | } }; |
| 32161 | 32000 | |
| 32162 | 32001 | if (opt_first_idx) |first_idx| { |
| ... | ... | @@ -32224,9 +32063,9 @@ fn resolvePeerTypesInner( |
| 32224 | 32063 | |
| 32225 | 32064 | if (!ty.isArrayOrVector(mod)) { |
| 32226 | 32065 | // Allow tuples of the correct length |
| 32227 | | const arr_like = sema.typeIsArrayLike(ty) orelse return .{ .bad_strat = .{ |
| 32228 | | .strat = s, |
| 32229 | | .peer_idx = i, |
| 32066 | const arr_like = sema.typeIsArrayLike(ty) orelse return .{ .conflict = .{ |
| 32067 | .peer_idx_a = strat_reason, |
| 32068 | .peer_idx_b = i, |
| 32230 | 32069 | } }; |
| 32231 | 32070 | |
| 32232 | 32071 | if (len) |expect_len| { |
| ... | ... | @@ -32266,7 +32105,6 @@ fn resolvePeerTypesInner( |
| 32266 | 32105 | src, |
| 32267 | 32106 | peer_tys, |
| 32268 | 32107 | peer_vals, |
| 32269 | | strat_reason, |
| 32270 | 32108 | )) { |
| 32271 | 32109 | .success => |ty| ty, |
| 32272 | 32110 | else => |result| return result, |
| ... | ... | @@ -32300,9 +32138,9 @@ fn resolvePeerTypesInner( |
| 32300 | 32138 | else => {}, |
| 32301 | 32139 | } |
| 32302 | 32140 | |
| 32303 | | if (!ty.isPtrAtRuntime(mod)) return .{ .bad_strat = .{ |
| 32304 | | .strat = s, |
| 32305 | | .peer_idx = i, |
| 32141 | if (!ty.isPtrAtRuntime(mod)) return .{ .conflict = .{ |
| 32142 | .peer_idx_a = strat_reason, |
| 32143 | .peer_idx_b = i, |
| 32306 | 32144 | } }; |
| 32307 | 32145 | |
| 32308 | 32146 | // Goes through optionals |
| ... | ... | @@ -32316,7 +32154,6 @@ fn resolvePeerTypesInner( |
| 32316 | 32154 | }; |
| 32317 | 32155 | |
| 32318 | 32156 | // Try peer -> cur, then cur -> peer |
| 32319 | | const old_pointee_type = ptr_info.pointee_type; |
| 32320 | 32157 | ptr_info.pointee_type = (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) orelse { |
| 32321 | 32158 | return .{ .conflict = .{ |
| 32322 | 32159 | .peer_idx_a = first_idx, |
| ... | ... | @@ -32325,8 +32162,8 @@ fn resolvePeerTypesInner( |
| 32325 | 32162 | }; |
| 32326 | 32163 | |
| 32327 | 32164 | if (ptr_info.sentinel != null and peer_info.sentinel != null) { |
| 32328 | | const peer_sent = try sema.coerceValueInMemory(block, ptr_info.sentinel.?, old_pointee_type, ptr_info.pointee_type, .unneeded); |
| 32329 | | const ptr_sent = try sema.coerceValueInMemory(block, peer_info.sentinel.?, peer_info.pointee_type, ptr_info.pointee_type, .unneeded); |
| 32165 | const peer_sent = try mod.getCoerced(ptr_info.sentinel.?, ptr_info.pointee_type); |
| 32166 | const ptr_sent = try mod.getCoerced(peer_info.sentinel.?, ptr_info.pointee_type); |
| 32330 | 32167 | if (ptr_sent.eql(peer_sent, ptr_info.pointee_type, mod)) { |
| 32331 | 32168 | ptr_info.sentinel = ptr_sent; |
| 32332 | 32169 | } else { |
| ... | ... | @@ -32379,18 +32216,18 @@ fn resolvePeerTypesInner( |
| 32379 | 32216 | .pointee_type = ty, |
| 32380 | 32217 | .@"addrspace" = target_util.defaultAddressSpace(target, .global_constant), |
| 32381 | 32218 | }, |
| 32382 | | else => return .{ .bad_strat = .{ |
| 32383 | | .strat = s, |
| 32384 | | .peer_idx = i, |
| 32219 | else => return .{ .conflict = .{ |
| 32220 | .peer_idx_a = strat_reason, |
| 32221 | .peer_idx_b = i, |
| 32385 | 32222 | } }, |
| 32386 | 32223 | }; |
| 32387 | 32224 | |
| 32388 | 32225 | switch (peer_info.size) { |
| 32389 | 32226 | .One, .Many => {}, |
| 32390 | 32227 | .Slice => opt_slice_idx = i, |
| 32391 | | .C => return .{ .bad_strat = .{ |
| 32392 | | .strat = s, |
| 32393 | | .peer_idx = i, |
| 32228 | .C => return .{ .conflict = .{ |
| 32229 | .peer_idx_a = strat_reason, |
| 32230 | .peer_idx_b = i, |
| 32394 | 32231 | } }, |
| 32395 | 32232 | } |
| 32396 | 32233 | |
| ... | ... | @@ -32605,10 +32442,8 @@ fn resolvePeerTypesInner( |
| 32605 | 32442 | no_sentinel: { |
| 32606 | 32443 | if (peer_sentinel == null) break :no_sentinel; |
| 32607 | 32444 | if (cur_sentinel == null) break :no_sentinel; |
| 32608 | | const peer_sent_ty = mod.intern_pool.typeOf(peer_sentinel.?.toIntern()).toType(); |
| 32609 | | const cur_sent_ty = mod.intern_pool.typeOf(cur_sentinel.?.toIntern()).toType(); |
| 32610 | | const peer_sent_coerced = try sema.coerceValueInMemory(block, peer_sentinel.?, peer_sent_ty, sentinel_ty, .unneeded); |
| 32611 | | const cur_sent_coerced = try sema.coerceValueInMemory(block, cur_sentinel.?, cur_sent_ty, sentinel_ty, .unneeded); |
| 32445 | const peer_sent_coerced = try mod.getCoerced(peer_sentinel.?, sentinel_ty); |
| 32446 | const cur_sent_coerced = try mod.getCoerced(cur_sentinel.?, sentinel_ty); |
| 32612 | 32447 | if (!peer_sent_coerced.eql(cur_sent_coerced, sentinel_ty, mod)) break :no_sentinel; |
| 32613 | 32448 | // Sentinels match |
| 32614 | 32449 | if (ptr_info.size == .One) { |
| ... | ... | @@ -32664,9 +32499,9 @@ fn resolvePeerTypesInner( |
| 32664 | 32499 | first_idx = i; |
| 32665 | 32500 | continue; |
| 32666 | 32501 | }; |
| 32667 | | if (ty.zigTypeTag(mod) != .Fn) return .{ .bad_strat = .{ |
| 32668 | | .strat = s, |
| 32669 | | .peer_idx = i, |
| 32502 | if (ty.zigTypeTag(mod) != .Fn) return .{ .conflict = .{ |
| 32503 | .peer_idx_a = strat_reason, |
| 32504 | .peer_idx_b = i, |
| 32670 | 32505 | } }; |
| 32671 | 32506 | // ty -> cur_ty |
| 32672 | 32507 | if (.ok == try sema.coerceInMemoryAllowedFns(block, cur_ty, ty, target, src, src)) { |
| ... | ... | @@ -32694,9 +32529,9 @@ fn resolvePeerTypesInner( |
| 32694 | 32529 | const ty = opt_ty orelse continue; |
| 32695 | 32530 | switch (ty.zigTypeTag(mod)) { |
| 32696 | 32531 | .EnumLiteral, .Enum, .Union => {}, |
| 32697 | | else => return .{ .bad_strat = .{ |
| 32698 | | .strat = s, |
| 32699 | | .peer_idx = i, |
| 32532 | else => return .{ .conflict = .{ |
| 32533 | .peer_idx_a = strat_reason, |
| 32534 | .peer_idx_b = i, |
| 32700 | 32535 | } }, |
| 32701 | 32536 | } |
| 32702 | 32537 | const cur_ty = opt_cur_ty orelse { |
| ... | ... | @@ -32751,9 +32586,9 @@ fn resolvePeerTypesInner( |
| 32751 | 32586 | const ty = opt_ty orelse continue; |
| 32752 | 32587 | switch (ty.zigTypeTag(mod)) { |
| 32753 | 32588 | .ComptimeInt => {}, |
| 32754 | | else => return .{ .bad_strat = .{ |
| 32755 | | .strat = s, |
| 32756 | | .peer_idx = i, |
| 32589 | else => return .{ .conflict = .{ |
| 32590 | .peer_idx_a = strat_reason, |
| 32591 | .peer_idx_b = i, |
| 32757 | 32592 | } }, |
| 32758 | 32593 | } |
| 32759 | 32594 | } |
| ... | ... | @@ -32765,9 +32600,9 @@ fn resolvePeerTypesInner( |
| 32765 | 32600 | const ty = opt_ty orelse continue; |
| 32766 | 32601 | switch (ty.zigTypeTag(mod)) { |
| 32767 | 32602 | .ComptimeInt, .ComptimeFloat => {}, |
| 32768 | | else => return .{ .bad_strat = .{ |
| 32769 | | .strat = s, |
| 32770 | | .peer_idx = i, |
| 32603 | else => return .{ .conflict = .{ |
| 32604 | .peer_idx_a = strat_reason, |
| 32605 | .peer_idx_b = i, |
| 32771 | 32606 | } }, |
| 32772 | 32607 | } |
| 32773 | 32608 | } |
| ... | ... | @@ -32789,18 +32624,18 @@ fn resolvePeerTypesInner( |
| 32789 | 32624 | switch (peer_tag) { |
| 32790 | 32625 | .ComptimeInt => { |
| 32791 | 32626 | // If the value is undefined, we can't refine to a fixed-width int |
| 32792 | | if (opt_val == null or opt_val.?.isUndef(mod)) return .{ .bad_strat = .{ |
| 32793 | | .strat = s, |
| 32794 | | .peer_idx = i, |
| 32627 | if (opt_val == null or opt_val.?.isUndef(mod)) return .{ .conflict = .{ |
| 32628 | .peer_idx_a = strat_reason, |
| 32629 | .peer_idx_b = i, |
| 32795 | 32630 | } }; |
| 32796 | 32631 | any_comptime_known = true; |
| 32797 | 32632 | ptr_opt_val.* = try sema.resolveLazyValue(opt_val.?); |
| 32798 | 32633 | continue; |
| 32799 | 32634 | }, |
| 32800 | 32635 | .Int => {}, |
| 32801 | | else => return .{ .bad_strat = .{ |
| 32802 | | .strat = s, |
| 32803 | | .peer_idx = i, |
| 32636 | else => return .{ .conflict = .{ |
| 32637 | .peer_idx_a = strat_reason, |
| 32638 | .peer_idx_b = i, |
| 32804 | 32639 | } }, |
| 32805 | 32640 | } |
| 32806 | 32641 | |
| ... | ... | @@ -32868,9 +32703,9 @@ fn resolvePeerTypesInner( |
| 32868 | 32703 | switch (ty.zigTypeTag(mod)) { |
| 32869 | 32704 | .ComptimeFloat, .ComptimeInt => {}, |
| 32870 | 32705 | .Int => { |
| 32871 | | if (opt_val == null) return .{ .bad_strat = .{ |
| 32872 | | .strat = s, |
| 32873 | | .peer_idx = i, |
| 32706 | if (opt_val == null) return .{ .conflict = .{ |
| 32707 | .peer_idx_a = strat_reason, |
| 32708 | .peer_idx_b = i, |
| 32874 | 32709 | } }; |
| 32875 | 32710 | }, |
| 32876 | 32711 | .Float => { |
| ... | ... | @@ -32890,9 +32725,9 @@ fn resolvePeerTypesInner( |
| 32890 | 32725 | opt_cur_ty = ty; |
| 32891 | 32726 | } |
| 32892 | 32727 | }, |
| 32893 | | else => return .{ .bad_strat = .{ |
| 32894 | | .strat = s, |
| 32895 | | .peer_idx = i, |
| 32728 | else => return .{ .conflict = .{ |
| 32729 | .peer_idx_a = strat_reason, |
| 32730 | .peer_idx_b = i, |
| 32896 | 32731 | } }, |
| 32897 | 32732 | } |
| 32898 | 32733 | } |
| ... | ... | @@ -32915,9 +32750,9 @@ fn resolvePeerTypesInner( |
| 32915 | 32750 | const ty = opt_ty orelse continue; |
| 32916 | 32751 | |
| 32917 | 32752 | if (!ty.isTupleOrAnonStruct(mod)) { |
| 32918 | | return .{ .bad_strat = .{ |
| 32919 | | .strat = s, |
| 32920 | | .peer_idx = i, |
| 32753 | return .{ .conflict = .{ |
| 32754 | .peer_idx_a = strat_reason, |
| 32755 | .peer_idx_b = i, |
| 32921 | 32756 | } }; |
| 32922 | 32757 | } |
| 32923 | 32758 | |
| ... | ... | @@ -32973,7 +32808,7 @@ fn resolvePeerTypesInner( |
| 32973 | 32808 | } |
| 32974 | 32809 | |
| 32975 | 32810 | // Resolve field type recursively |
| 32976 | | field_ty.* = switch (try sema.resolvePeerTypesInner(block, src, sub_peer_tys, sub_peer_vals, strat_reason)) { |
| 32811 | field_ty.* = switch (try sema.resolvePeerTypesInner(block, src, sub_peer_tys, sub_peer_vals)) { |
| 32977 | 32812 | .success => |ty| ty.toIntern(), |
| 32978 | 32813 | else => |result| { |
| 32979 | 32814 | const result_buf = try sema.arena.create(PeerResolveResult); |
| ... | ... | @@ -35538,7 +35373,7 @@ fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value |
| 35538 | 35373 | // Move mutable decl values to the InternPool and assert other decls are already in |
| 35539 | 35374 | // the InternPool. |
| 35540 | 35375 | const uncoerced_val = if (deref.is_mutable) try tv.val.intern(tv.ty, mod) else tv.val.toIntern(); |
| 35541 | | const coerced_val = try sema.coerceValueInMemory(block, uncoerced_val.toValue(), tv.ty, load_ty, src); |
| 35376 | const coerced_val = try mod.getCoerced(uncoerced_val.toValue(), load_ty); |
| 35542 | 35377 | return .{ .val = coerced_val }; |
| 35543 | 35378 | } |
| 35544 | 35379 | } |