| ... | @@ -23069,7 +23069,7 @@ fn analyzeMinMax( | ... | @@ -23069,7 +23069,7 @@ fn analyzeMinMax( |
| 23069 | if (std.debug.runtime_safety) { | 23069 | if (std.debug.runtime_safety) { |
| 23070 | assert(try sema.intFitsInType(val, refined_ty, null)); | 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 | break :refined refined_ty; | 23075 | break :refined refined_ty; |
| ... | @@ -26610,7 +26610,7 @@ fn coerceExtra( | ... | @@ -26610,7 +26610,7 @@ fn coerceExtra( |
| 26610 | var in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src); | 26610 | var in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src); |
| 26611 | if (in_memory_result == .ok) { | 26611 | if (in_memory_result == .ok) { |
| 26612 | if (maybe_inst_val) |val| { | 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 | try sema.requireRuntimeBlock(block, inst_src, null); | 26615 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 26616 | return block.addBitCast(dest_ty, inst); | 26616 | return block.addBitCast(dest_ty, inst); |
| ... | @@ -27278,89 +27278,12 @@ fn coerceExtra( | ... | @@ -27278,89 +27278,12 @@ fn coerceExtra( |
| 27278 | return sema.failWithOwnedErrorMsg(msg); | 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 | fn coerceInMemory( | 27281 | fn coerceInMemory( |
| 27356 | sema: *Sema, | 27282 | sema: *Sema, |
| 27357 | block: *Block, | | |
| 27358 | val: Value, | 27283 | val: Value, |
| 27359 | src_ty: Type, | | |
| 27360 | dst_ty: Type, | 27284 | dst_ty: Type, |
| 27361 | dst_ty_src: LazySrcLoc, | | |
| 27362 | ) CompileError!Air.Inst.Ref { | 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 | const InMemoryCoercionResult = union(enum) { | 27289 | const InMemoryCoercionResult = union(enum) { |
| ... | @@ -29820,7 +29743,7 @@ fn coerceArrayLike( | ... | @@ -29820,7 +29743,7 @@ fn coerceArrayLike( |
| 29820 | if (in_memory_result == .ok) { | 29743 | if (in_memory_result == .ok) { |
| 29821 | if (try sema.resolveMaybeUndefVal(inst)) |inst_val| { | 29744 | if (try sema.resolveMaybeUndefVal(inst)) |inst_val| { |
| 29822 | // These types share the same comptime value representation. | 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 | try sema.requireRuntimeBlock(block, inst_src, null); | 29748 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 29826 | return block.addBitCast(dest_ty, inst); | 29749 | return block.addBitCast(dest_ty, inst); |
| ... | @@ -31653,40 +31576,12 @@ const PeerResolveStrategy = enum { | ... | @@ -31653,40 +31576,12 @@ const PeerResolveStrategy = enum { |
| 31653 | /// The peers must all be of the same type. | 31576 | /// The peers must all be of the same type. |
| 31654 | exact, | 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 | /// Given two strategies, find a strategy that satisfies both, if one exists. If no such | 31579 | /// Given two strategies, find a strategy that satisfies both, if one exists. If no such |
| 31685 | /// strategy exists, any strategy may be returned; an error will be emitted when the caller | 31580 | /// strategy exists, any strategy may be returned; an error will be emitted when the caller |
| 31686 | /// attempts to use the strategy to resolve the type. | 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 | 31582 | /// Strategy `a` comes from the peer in `reason_peer`, 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. | 31583 | /// index `b_peer_idx`. `reason_peer` is updated to reflect the reason for the new strategy. |
| 31689 | fn merge(a: PeerResolveStrategy, b: PeerResolveStrategy, reason: *Reason, b_peer_idx: usize) PeerResolveStrategy { | 31584 | fn merge(a: PeerResolveStrategy, b: PeerResolveStrategy, reason_peer: *usize, b_peer_idx: usize) PeerResolveStrategy { |
| 31690 | // Our merging should be order-independent. Thus, even though the union order is arbitrary, | 31585 | // Our merging should be order-independent. Thus, even though the union order is arbitrary, |
| 31691 | // by sorting the tags and switching first on the smaller, we have half as many cases to | 31586 | // by sorting the tags and switching first on the smaller, we have half as many cases to |
| 31692 | // worry about (since we avoid the duplicates). | 31587 | // worry about (since we avoid the duplicates). |
| ... | @@ -31698,14 +31593,13 @@ const PeerResolveStrategy = enum { | ... | @@ -31698,14 +31593,13 @@ const PeerResolveStrategy = enum { |
| 31698 | all_s0, | 31593 | all_s0, |
| 31699 | all_s1, | 31594 | all_s1, |
| 31700 | either, | 31595 | either, |
| 31701 | both, | | |
| 31702 | }; | 31596 | }; |
| 31703 | | 31597 | |
| 31704 | const res: struct { ReasonMethod, PeerResolveStrategy } = switch (s0) { | 31598 | const res: struct { ReasonMethod, PeerResolveStrategy } = switch (s0) { |
| 31705 | .unknown => .{ .all_s1, s1 }, | 31599 | .unknown => .{ .all_s1, s1 }, |
| 31706 | .error_set => switch (s1) { | 31600 | .error_set => switch (s1) { |
| 31707 | .error_set => .{ .either, .error_set }, | 31601 | .error_set => .{ .either, .error_set }, |
| 31708 | else => .{ .both, .error_union }, | 31602 | else => .{ .all_s0, .error_union }, |
| 31709 | }, | 31603 | }, |
| 31710 | .error_union => switch (s1) { | 31604 | .error_union => switch (s1) { |
| 31711 | .error_union => .{ .either, .error_union }, | 31605 | .error_union => .{ .either, .error_union }, |
| ... | @@ -31714,7 +31608,7 @@ const PeerResolveStrategy = enum { | ... | @@ -31714,7 +31608,7 @@ const PeerResolveStrategy = enum { |
| 31714 | .nullable => switch (s1) { | 31608 | .nullable => switch (s1) { |
| 31715 | .nullable => .{ .either, .nullable }, | 31609 | .nullable => .{ .either, .nullable }, |
| 31716 | .c_ptr => .{ .all_s1, .c_ptr }, | 31610 | .c_ptr => .{ .all_s1, .c_ptr }, |
| 31717 | else => .{ .both, .optional }, | 31611 | else => .{ .all_s0, .optional }, |
| 31718 | }, | 31612 | }, |
| 31719 | .optional => switch (s1) { | 31613 | .optional => switch (s1) { |
| 31720 | .optional => .{ .either, .optional }, | 31614 | .optional => .{ .either, .optional }, |
| ... | @@ -31772,23 +31666,17 @@ const PeerResolveStrategy = enum { | ... | @@ -31772,23 +31666,17 @@ const PeerResolveStrategy = enum { |
| 31772 | switch (res[0]) { | 31666 | switch (res[0]) { |
| 31773 | .all_s0 => { | 31667 | .all_s0 => { |
| 31774 | if (!s0_is_a) { | 31668 | if (!s0_is_a) { |
| 31775 | reason.reset(); | 31669 | reason_peer.* = b_peer_idx; |
| 31776 | reason.peers.set(b_peer_idx); | | |
| 31777 | } | 31670 | } |
| 31778 | }, | 31671 | }, |
| 31779 | .all_s1 => { | 31672 | .all_s1 => { |
| 31780 | if (s0_is_a) { | 31673 | if (s0_is_a) { |
| 31781 | reason.reset(); | 31674 | reason_peer.* = b_peer_idx; |
| 31782 | reason.peers.set(b_peer_idx); | | |
| 31783 | } | 31675 | } |
| 31784 | }, | 31676 | }, |
| 31785 | .either => { | 31677 | .either => { |
| 31786 | // Prefer b, since it's a single peer | 31678 | // Prefer the earliest peer |
| 31787 | reason.reset(); | 31679 | reason_peer.* = @min(reason_peer.*, b_peer_idx); |
| 31788 | reason.peers.set(b_peer_idx); | | |
| 31789 | }, | | |
| 31790 | .both => { | | |
| 31791 | reason.peers.set(b_peer_idx); | | |
| 31792 | }, | 31680 | }, |
| 31793 | } | 31681 | } |
| 31794 | | 31682 | |
| ... | @@ -31820,12 +31708,7 @@ const PeerResolveStrategy = enum { | ... | @@ -31820,12 +31708,7 @@ const PeerResolveStrategy = enum { |
| 31820 | const PeerResolveResult = union(enum) { | 31708 | const PeerResolveResult = union(enum) { |
| 31821 | /// The peer type resolution was successful, and resulted in the given type. | 31709 | /// The peer type resolution was successful, and resulted in the given type. |
| 31822 | success: Type, | 31710 | success: Type, |
| 31823 | /// The chosen strategy was incompatible with the given peer. | 31711 | /// There was some generic conflict between two peers. |
| 31824 | bad_strat: struct { | | |
| 31825 | strat: PeerResolveStrategy, | | |
| 31826 | peer_idx: usize, | | |
| 31827 | }, | | |
| 31828 | /// There was some conflict between two specific peers. | | |
| 31829 | conflict: struct { | 31712 | conflict: struct { |
| 31830 | peer_idx_a: usize, | 31713 | peer_idx_a: usize, |
| 31831 | peer_idx_b: usize, | 31714 | peer_idx_b: usize, |
| ... | @@ -31847,7 +31730,6 @@ const PeerResolveResult = union(enum) { | ... | @@ -31847,7 +31730,6 @@ const PeerResolveResult = union(enum) { |
| 31847 | src: LazySrcLoc, | 31730 | src: LazySrcLoc, |
| 31848 | instructions: []const Air.Inst.Ref, | 31731 | instructions: []const Air.Inst.Ref, |
| 31849 | candidate_srcs: Module.PeerTypeCandidateSrc, | 31732 | candidate_srcs: Module.PeerTypeCandidateSrc, |
| 31850 | strat_reason: PeerResolveStrategy.Reason, | | |
| 31851 | ) !*Module.ErrorMsg { | 31733 | ) !*Module.ErrorMsg { |
| 31852 | const mod = sema.mod; | 31734 | const mod = sema.mod; |
| 31853 | const decl_ptr = mod.declPtr(block.src_decl); | 31735 | const decl_ptr = mod.declPtr(block.src_decl); |
| ... | @@ -31867,41 +31749,6 @@ const PeerResolveResult = union(enum) { | ... | @@ -31867,41 +31749,6 @@ const PeerResolveResult = union(enum) { |
| 31867 | | 31749 | |
| 31868 | switch (cur) { | 31750 | switch (cur) { |
| 31869 | .success => unreachable, | 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 | .conflict => |conflict| { | 31752 | .conflict => |conflict| { |
| 31906 | // Fall through to two-peer conflict handling below | 31753 | // Fall through to two-peer conflict handling below |
| 31907 | conflict_idx = .{ | 31754 | conflict_idx = .{ |
| ... | @@ -31925,7 +31772,7 @@ const PeerResolveResult = union(enum) { | ... | @@ -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 | if (conflict_idx[1] < conflict_idx[0]) { | 31777 | if (conflict_idx[1] < conflict_idx[0]) { |
| 31931 | // b comes first in source, so it's better if it comes first in the error | 31778 | // b comes first in source, so it's better if it comes first in the error |
| ... | @@ -31987,14 +31834,10 @@ fn resolvePeerTypes( | ... | @@ -31987,14 +31834,10 @@ fn resolvePeerTypes( |
| 31987 | val.* = try sema.resolveMaybeUndefVal(inst); | 31834 | val.* = try sema.resolveMaybeUndefVal(inst); |
| 31988 | } | 31835 | } |
| 31989 | | 31836 | |
| 31990 | var strat_reason: PeerResolveStrategy.Reason = .{ | 31837 | switch (try sema.resolvePeerTypesInner(block, src, peer_tys, peer_vals)) { |
| 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)) { | | |
| 31995 | .success => |ty| return ty, | 31838 | .success => |ty| return ty, |
| 31996 | else => |result| { | 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 | return sema.failWithOwnedErrorMsg(msg); | 31841 | return sema.failWithOwnedErrorMsg(msg); |
| 31999 | }, | 31842 | }, |
| 32000 | } | 31843 | } |
| ... | @@ -32006,16 +31849,14 @@ fn resolvePeerTypesInner( | ... | @@ -32006,16 +31849,14 @@ fn resolvePeerTypesInner( |
| 32006 | src: LazySrcLoc, | 31849 | src: LazySrcLoc, |
| 32007 | peer_tys: []?Type, | 31850 | peer_tys: []?Type, |
| 32008 | peer_vals: []?Value, | 31851 | peer_vals: []?Value, |
| 32009 | strat_reason: *PeerResolveStrategy.Reason, | | |
| 32010 | ) !PeerResolveResult { | 31852 | ) !PeerResolveResult { |
| 32011 | const mod = sema.mod; | 31853 | const mod = sema.mod; |
| 32012 | | 31854 | |
| 32013 | strat_reason.reset(); | 31855 | var strat_reason: usize = 0; |
| 32014 | | | |
| 32015 | var s: PeerResolveStrategy = .unknown; | 31856 | var s: PeerResolveStrategy = .unknown; |
| 32016 | for (peer_tys, 0..) |opt_ty, i| { | 31857 | for (peer_tys, 0..) |opt_ty, i| { |
| 32017 | const ty = opt_ty orelse continue; | 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 | if (s == .unknown) { | 31862 | if (s == .unknown) { |
| ... | @@ -32041,9 +31882,9 @@ fn resolvePeerTypesInner( | ... | @@ -32041,9 +31882,9 @@ fn resolvePeerTypesInner( |
| 32041 | var final_set: ?Type = null; | 31882 | var final_set: ?Type = null; |
| 32042 | for (peer_tys, 0..) |opt_ty, i| { | 31883 | for (peer_tys, 0..) |opt_ty, i| { |
| 32043 | const ty = opt_ty orelse continue; | 31884 | const ty = opt_ty orelse continue; |
| 32044 | if (ty.zigTypeTag(mod) != .ErrorSet) return .{ .bad_strat = .{ | 31885 | if (ty.zigTypeTag(mod) != .ErrorSet) return .{ .conflict = .{ |
| 32045 | .strat = s, | 31886 | .peer_idx_a = strat_reason, |
| 32046 | .peer_idx = i, | 31887 | .peer_idx_b = i, |
| 32047 | } }; | 31888 | } }; |
| 32048 | if (final_set) |cur_set| { | 31889 | if (final_set) |cur_set| { |
| 32049 | final_set = try sema.maybeMergeErrorSets(block, src, cur_set, ty); | 31890 | final_set = try sema.maybeMergeErrorSets(block, src, cur_set, ty); |
| ... | @@ -32091,7 +31932,6 @@ fn resolvePeerTypesInner( | ... | @@ -32091,7 +31932,6 @@ fn resolvePeerTypesInner( |
| 32091 | src, | 31932 | src, |
| 32092 | peer_tys, | 31933 | peer_tys, |
| 32093 | peer_vals, | 31934 | peer_vals, |
| 32094 | strat_reason, | | |
| 32095 | )) { | 31935 | )) { |
| 32096 | .success => |ty| ty, | 31936 | .success => |ty| ty, |
| 32097 | else => |result| return result, | 31937 | else => |result| return result, |
| ... | @@ -32102,9 +31942,9 @@ fn resolvePeerTypesInner( | ... | @@ -32102,9 +31942,9 @@ fn resolvePeerTypesInner( |
| 32102 | .nullable => { | 31942 | .nullable => { |
| 32103 | for (peer_tys, 0..) |opt_ty, i| { | 31943 | for (peer_tys, 0..) |opt_ty, i| { |
| 32104 | const ty = opt_ty orelse continue; | 31944 | const ty = opt_ty orelse continue; |
| 32105 | if (!ty.eql(Type.null, mod)) return .{ .bad_strat = .{ | 31945 | if (!ty.eql(Type.null, mod)) return .{ .conflict = .{ |
| 32106 | .strat = s, | 31946 | .peer_idx_a = strat_reason, |
| 32107 | .peer_idx = i, | 31947 | .peer_idx_b = i, |
| 32108 | } }; | 31948 | } }; |
| 32109 | } | 31949 | } |
| 32110 | return .{ .success = Type.null }; | 31950 | return .{ .success = Type.null }; |
| ... | @@ -32130,7 +31970,6 @@ fn resolvePeerTypesInner( | ... | @@ -32130,7 +31970,6 @@ fn resolvePeerTypesInner( |
| 32130 | src, | 31970 | src, |
| 32131 | peer_tys, | 31971 | peer_tys, |
| 32132 | peer_vals, | 31972 | peer_vals, |
| 32133 | strat_reason, | | |
| 32134 | )) { | 31973 | )) { |
| 32135 | .success => |ty| ty, | 31974 | .success => |ty| ty, |
| 32136 | else => |result| return result, | 31975 | else => |result| return result, |
| ... | @@ -32154,9 +31993,9 @@ fn resolvePeerTypesInner( | ... | @@ -32154,9 +31993,9 @@ fn resolvePeerTypesInner( |
| 32154 | | 31993 | |
| 32155 | if (!ty.isArrayOrVector(mod)) { | 31994 | if (!ty.isArrayOrVector(mod)) { |
| 32156 | // We allow tuples of the correct length. We won't validate their elem type, since the elements can be coerced. | 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 = .{ | 31996 | const arr_like = sema.typeIsArrayLike(ty) orelse return .{ .conflict = .{ |
| 32158 | .strat = s, | 31997 | .peer_idx_a = strat_reason, |
| 32159 | .peer_idx = i, | 31998 | .peer_idx_b = i, |
| 32160 | } }; | 31999 | } }; |
| 32161 | | 32000 | |
| 32162 | if (opt_first_idx) |first_idx| { | 32001 | if (opt_first_idx) |first_idx| { |
| ... | @@ -32224,9 +32063,9 @@ fn resolvePeerTypesInner( | ... | @@ -32224,9 +32063,9 @@ fn resolvePeerTypesInner( |
| 32224 | | 32063 | |
| 32225 | if (!ty.isArrayOrVector(mod)) { | 32064 | if (!ty.isArrayOrVector(mod)) { |
| 32226 | // Allow tuples of the correct length | 32065 | // Allow tuples of the correct length |
| 32227 | const arr_like = sema.typeIsArrayLike(ty) orelse return .{ .bad_strat = .{ | 32066 | const arr_like = sema.typeIsArrayLike(ty) orelse return .{ .conflict = .{ |
| 32228 | .strat = s, | 32067 | .peer_idx_a = strat_reason, |
| 32229 | .peer_idx = i, | 32068 | .peer_idx_b = i, |
| 32230 | } }; | 32069 | } }; |
| 32231 | | 32070 | |
| 32232 | if (len) |expect_len| { | 32071 | if (len) |expect_len| { |
| ... | @@ -32266,7 +32105,6 @@ fn resolvePeerTypesInner( | ... | @@ -32266,7 +32105,6 @@ fn resolvePeerTypesInner( |
| 32266 | src, | 32105 | src, |
| 32267 | peer_tys, | 32106 | peer_tys, |
| 32268 | peer_vals, | 32107 | peer_vals, |
| 32269 | strat_reason, | | |
| 32270 | )) { | 32108 | )) { |
| 32271 | .success => |ty| ty, | 32109 | .success => |ty| ty, |
| 32272 | else => |result| return result, | 32110 | else => |result| return result, |
| ... | @@ -32300,9 +32138,9 @@ fn resolvePeerTypesInner( | ... | @@ -32300,9 +32138,9 @@ fn resolvePeerTypesInner( |
| 32300 | else => {}, | 32138 | else => {}, |
| 32301 | } | 32139 | } |
| 32302 | | 32140 | |
| 32303 | if (!ty.isPtrAtRuntime(mod)) return .{ .bad_strat = .{ | 32141 | if (!ty.isPtrAtRuntime(mod)) return .{ .conflict = .{ |
| 32304 | .strat = s, | 32142 | .peer_idx_a = strat_reason, |
| 32305 | .peer_idx = i, | 32143 | .peer_idx_b = i, |
| 32306 | } }; | 32144 | } }; |
| 32307 | | 32145 | |
| 32308 | // Goes through optionals | 32146 | // Goes through optionals |
| ... | @@ -32316,7 +32154,6 @@ fn resolvePeerTypesInner( | ... | @@ -32316,7 +32154,6 @@ fn resolvePeerTypesInner( |
| 32316 | }; | 32154 | }; |
| 32317 | | 32155 | |
| 32318 | // Try peer -> cur, then cur -> peer | 32156 | // Try peer -> cur, then cur -> peer |
| 32319 | const old_pointee_type = ptr_info.pointee_type; | | |
| 32320 | ptr_info.pointee_type = (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) orelse { | 32157 | ptr_info.pointee_type = (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) orelse { |
| 32321 | return .{ .conflict = .{ | 32158 | return .{ .conflict = .{ |
| 32322 | .peer_idx_a = first_idx, | 32159 | .peer_idx_a = first_idx, |
| ... | @@ -32325,8 +32162,8 @@ fn resolvePeerTypesInner( | ... | @@ -32325,8 +32162,8 @@ fn resolvePeerTypesInner( |
| 32325 | }; | 32162 | }; |
| 32326 | | 32163 | |
| 32327 | if (ptr_info.sentinel != null and peer_info.sentinel != null) { | 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); | 32165 | const peer_sent = try mod.getCoerced(ptr_info.sentinel.?, ptr_info.pointee_type); |
| 32329 | const ptr_sent = try sema.coerceValueInMemory(block, peer_info.sentinel.?, peer_info.pointee_type, ptr_info.pointee_type, .unneeded); | 32166 | const ptr_sent = try mod.getCoerced(peer_info.sentinel.?, ptr_info.pointee_type); |
| 32330 | if (ptr_sent.eql(peer_sent, ptr_info.pointee_type, mod)) { | 32167 | if (ptr_sent.eql(peer_sent, ptr_info.pointee_type, mod)) { |
| 32331 | ptr_info.sentinel = ptr_sent; | 32168 | ptr_info.sentinel = ptr_sent; |
| 32332 | } else { | 32169 | } else { |
| ... | @@ -32379,18 +32216,18 @@ fn resolvePeerTypesInner( | ... | @@ -32379,18 +32216,18 @@ fn resolvePeerTypesInner( |
| 32379 | .pointee_type = ty, | 32216 | .pointee_type = ty, |
| 32380 | .@"addrspace" = target_util.defaultAddressSpace(target, .global_constant), | 32217 | .@"addrspace" = target_util.defaultAddressSpace(target, .global_constant), |
| 32381 | }, | 32218 | }, |
| 32382 | else => return .{ .bad_strat = .{ | 32219 | else => return .{ .conflict = .{ |
| 32383 | .strat = s, | 32220 | .peer_idx_a = strat_reason, |
| 32384 | .peer_idx = i, | 32221 | .peer_idx_b = i, |
| 32385 | } }, | 32222 | } }, |
| 32386 | }; | 32223 | }; |
| 32387 | | 32224 | |
| 32388 | switch (peer_info.size) { | 32225 | switch (peer_info.size) { |
| 32389 | .One, .Many => {}, | 32226 | .One, .Many => {}, |
| 32390 | .Slice => opt_slice_idx = i, | 32227 | .Slice => opt_slice_idx = i, |
| 32391 | .C => return .{ .bad_strat = .{ | 32228 | .C => return .{ .conflict = .{ |
| 32392 | .strat = s, | 32229 | .peer_idx_a = strat_reason, |
| 32393 | .peer_idx = i, | 32230 | .peer_idx_b = i, |
| 32394 | } }, | 32231 | } }, |
| 32395 | } | 32232 | } |
| 32396 | | 32233 | |
| ... | @@ -32605,10 +32442,8 @@ fn resolvePeerTypesInner( | ... | @@ -32605,10 +32442,8 @@ fn resolvePeerTypesInner( |
| 32605 | no_sentinel: { | 32442 | no_sentinel: { |
| 32606 | if (peer_sentinel == null) break :no_sentinel; | 32443 | if (peer_sentinel == null) break :no_sentinel; |
| 32607 | if (cur_sentinel == null) break :no_sentinel; | 32444 | if (cur_sentinel == null) break :no_sentinel; |
| 32608 | const peer_sent_ty = mod.intern_pool.typeOf(peer_sentinel.?.toIntern()).toType(); | 32445 | const peer_sent_coerced = try mod.getCoerced(peer_sentinel.?, sentinel_ty); |
| 32609 | const cur_sent_ty = mod.intern_pool.typeOf(cur_sentinel.?.toIntern()).toType(); | 32446 | const cur_sent_coerced = try mod.getCoerced(cur_sentinel.?, sentinel_ty); |
| 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); | | |
| 32612 | if (!peer_sent_coerced.eql(cur_sent_coerced, sentinel_ty, mod)) break :no_sentinel; | 32447 | if (!peer_sent_coerced.eql(cur_sent_coerced, sentinel_ty, mod)) break :no_sentinel; |
| 32613 | // Sentinels match | 32448 | // Sentinels match |
| 32614 | if (ptr_info.size == .One) { | 32449 | if (ptr_info.size == .One) { |
| ... | @@ -32664,9 +32499,9 @@ fn resolvePeerTypesInner( | ... | @@ -32664,9 +32499,9 @@ fn resolvePeerTypesInner( |
| 32664 | first_idx = i; | 32499 | first_idx = i; |
| 32665 | continue; | 32500 | continue; |
| 32666 | }; | 32501 | }; |
| 32667 | if (ty.zigTypeTag(mod) != .Fn) return .{ .bad_strat = .{ | 32502 | if (ty.zigTypeTag(mod) != .Fn) return .{ .conflict = .{ |
| 32668 | .strat = s, | 32503 | .peer_idx_a = strat_reason, |
| 32669 | .peer_idx = i, | 32504 | .peer_idx_b = i, |
| 32670 | } }; | 32505 | } }; |
| 32671 | // ty -> cur_ty | 32506 | // ty -> cur_ty |
| 32672 | if (.ok == try sema.coerceInMemoryAllowedFns(block, cur_ty, ty, target, src, src)) { | 32507 | if (.ok == try sema.coerceInMemoryAllowedFns(block, cur_ty, ty, target, src, src)) { |
| ... | @@ -32694,9 +32529,9 @@ fn resolvePeerTypesInner( | ... | @@ -32694,9 +32529,9 @@ fn resolvePeerTypesInner( |
| 32694 | const ty = opt_ty orelse continue; | 32529 | const ty = opt_ty orelse continue; |
| 32695 | switch (ty.zigTypeTag(mod)) { | 32530 | switch (ty.zigTypeTag(mod)) { |
| 32696 | .EnumLiteral, .Enum, .Union => {}, | 32531 | .EnumLiteral, .Enum, .Union => {}, |
| 32697 | else => return .{ .bad_strat = .{ | 32532 | else => return .{ .conflict = .{ |
| 32698 | .strat = s, | 32533 | .peer_idx_a = strat_reason, |
| 32699 | .peer_idx = i, | 32534 | .peer_idx_b = i, |
| 32700 | } }, | 32535 | } }, |
| 32701 | } | 32536 | } |
| 32702 | const cur_ty = opt_cur_ty orelse { | 32537 | const cur_ty = opt_cur_ty orelse { |
| ... | @@ -32751,9 +32586,9 @@ fn resolvePeerTypesInner( | ... | @@ -32751,9 +32586,9 @@ fn resolvePeerTypesInner( |
| 32751 | const ty = opt_ty orelse continue; | 32586 | const ty = opt_ty orelse continue; |
| 32752 | switch (ty.zigTypeTag(mod)) { | 32587 | switch (ty.zigTypeTag(mod)) { |
| 32753 | .ComptimeInt => {}, | 32588 | .ComptimeInt => {}, |
| 32754 | else => return .{ .bad_strat = .{ | 32589 | else => return .{ .conflict = .{ |
| 32755 | .strat = s, | 32590 | .peer_idx_a = strat_reason, |
| 32756 | .peer_idx = i, | 32591 | .peer_idx_b = i, |
| 32757 | } }, | 32592 | } }, |
| 32758 | } | 32593 | } |
| 32759 | } | 32594 | } |
| ... | @@ -32765,9 +32600,9 @@ fn resolvePeerTypesInner( | ... | @@ -32765,9 +32600,9 @@ fn resolvePeerTypesInner( |
| 32765 | const ty = opt_ty orelse continue; | 32600 | const ty = opt_ty orelse continue; |
| 32766 | switch (ty.zigTypeTag(mod)) { | 32601 | switch (ty.zigTypeTag(mod)) { |
| 32767 | .ComptimeInt, .ComptimeFloat => {}, | 32602 | .ComptimeInt, .ComptimeFloat => {}, |
| 32768 | else => return .{ .bad_strat = .{ | 32603 | else => return .{ .conflict = .{ |
| 32769 | .strat = s, | 32604 | .peer_idx_a = strat_reason, |
| 32770 | .peer_idx = i, | 32605 | .peer_idx_b = i, |
| 32771 | } }, | 32606 | } }, |
| 32772 | } | 32607 | } |
| 32773 | } | 32608 | } |
| ... | @@ -32789,18 +32624,18 @@ fn resolvePeerTypesInner( | ... | @@ -32789,18 +32624,18 @@ fn resolvePeerTypesInner( |
| 32789 | switch (peer_tag) { | 32624 | switch (peer_tag) { |
| 32790 | .ComptimeInt => { | 32625 | .ComptimeInt => { |
| 32791 | // If the value is undefined, we can't refine to a fixed-width int | 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 = .{ | 32627 | if (opt_val == null or opt_val.?.isUndef(mod)) return .{ .conflict = .{ |
| 32793 | .strat = s, | 32628 | .peer_idx_a = strat_reason, |
| 32794 | .peer_idx = i, | 32629 | .peer_idx_b = i, |
| 32795 | } }; | 32630 | } }; |
| 32796 | any_comptime_known = true; | 32631 | any_comptime_known = true; |
| 32797 | ptr_opt_val.* = try sema.resolveLazyValue(opt_val.?); | 32632 | ptr_opt_val.* = try sema.resolveLazyValue(opt_val.?); |
| 32798 | continue; | 32633 | continue; |
| 32799 | }, | 32634 | }, |
| 32800 | .Int => {}, | 32635 | .Int => {}, |
| 32801 | else => return .{ .bad_strat = .{ | 32636 | else => return .{ .conflict = .{ |
| 32802 | .strat = s, | 32637 | .peer_idx_a = strat_reason, |
| 32803 | .peer_idx = i, | 32638 | .peer_idx_b = i, |
| 32804 | } }, | 32639 | } }, |
| 32805 | } | 32640 | } |
| 32806 | | 32641 | |
| ... | @@ -32868,9 +32703,9 @@ fn resolvePeerTypesInner( | ... | @@ -32868,9 +32703,9 @@ fn resolvePeerTypesInner( |
| 32868 | switch (ty.zigTypeTag(mod)) { | 32703 | switch (ty.zigTypeTag(mod)) { |
| 32869 | .ComptimeFloat, .ComptimeInt => {}, | 32704 | .ComptimeFloat, .ComptimeInt => {}, |
| 32870 | .Int => { | 32705 | .Int => { |
| 32871 | if (opt_val == null) return .{ .bad_strat = .{ | 32706 | if (opt_val == null) return .{ .conflict = .{ |
| 32872 | .strat = s, | 32707 | .peer_idx_a = strat_reason, |
| 32873 | .peer_idx = i, | 32708 | .peer_idx_b = i, |
| 32874 | } }; | 32709 | } }; |
| 32875 | }, | 32710 | }, |
| 32876 | .Float => { | 32711 | .Float => { |
| ... | @@ -32890,9 +32725,9 @@ fn resolvePeerTypesInner( | ... | @@ -32890,9 +32725,9 @@ fn resolvePeerTypesInner( |
| 32890 | opt_cur_ty = ty; | 32725 | opt_cur_ty = ty; |
| 32891 | } | 32726 | } |
| 32892 | }, | 32727 | }, |
| 32893 | else => return .{ .bad_strat = .{ | 32728 | else => return .{ .conflict = .{ |
| 32894 | .strat = s, | 32729 | .peer_idx_a = strat_reason, |
| 32895 | .peer_idx = i, | 32730 | .peer_idx_b = i, |
| 32896 | } }, | 32731 | } }, |
| 32897 | } | 32732 | } |
| 32898 | } | 32733 | } |
| ... | @@ -32915,9 +32750,9 @@ fn resolvePeerTypesInner( | ... | @@ -32915,9 +32750,9 @@ fn resolvePeerTypesInner( |
| 32915 | const ty = opt_ty orelse continue; | 32750 | const ty = opt_ty orelse continue; |
| 32916 | | 32751 | |
| 32917 | if (!ty.isTupleOrAnonStruct(mod)) { | 32752 | if (!ty.isTupleOrAnonStruct(mod)) { |
| 32918 | return .{ .bad_strat = .{ | 32753 | return .{ .conflict = .{ |
| 32919 | .strat = s, | 32754 | .peer_idx_a = strat_reason, |
| 32920 | .peer_idx = i, | 32755 | .peer_idx_b = i, |
| 32921 | } }; | 32756 | } }; |
| 32922 | } | 32757 | } |
| 32923 | | 32758 | |
| ... | @@ -32973,7 +32808,7 @@ fn resolvePeerTypesInner( | ... | @@ -32973,7 +32808,7 @@ fn resolvePeerTypesInner( |
| 32973 | } | 32808 | } |
| 32974 | | 32809 | |
| 32975 | // Resolve field type recursively | 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 | .success => |ty| ty.toIntern(), | 32812 | .success => |ty| ty.toIntern(), |
| 32978 | else => |result| { | 32813 | else => |result| { |
| 32979 | const result_buf = try sema.arena.create(PeerResolveResult); | 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,7 +35373,7 @@ fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value |
| 35538 | // Move mutable decl values to the InternPool and assert other decls are already in | 35373 | // Move mutable decl values to the InternPool and assert other decls are already in |
| 35539 | // the InternPool. | 35374 | // the InternPool. |
| 35540 | const uncoerced_val = if (deref.is_mutable) try tv.val.intern(tv.ty, mod) else tv.val.toIntern(); | 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 | return .{ .val = coerced_val }; | 35377 | return .{ .val = coerced_val }; |
| 35543 | } | 35378 | } |
| 35544 | } | 35379 | } |