diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/InternPool.zig | 93 | ||||
| -rw-r--r-- | src/Sema.zig | 311 |
2 files changed, 166 insertions, 238 deletions
diff --git a/src/InternPool.zig b/src/InternPool.zig index c208fcf18a..4da4790e2f 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -4568,6 +4568,7 @@ pub fn sliceLen(ip: *const InternPool, i: Index) Index { /// * int <=> int /// * int <=> enum /// * enum_literal => enum +/// * float <=> float /// * ptr <=> ptr /// * opt ptr <=> ptr /// * opt ptr <=> opt ptr @@ -4579,6 +4580,7 @@ pub fn sliceLen(ip: *const InternPool, i: Index) Index { /// * error set => error union /// * payload => error union /// * fn <=> fn +/// * aggregate <=> aggregate (where children can also be coerced) pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index { const old_ty = ip.typeOf(val); if (old_ty == new_ty) return val; @@ -4623,6 +4625,23 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al else => if (ip.isIntegerType(new_ty)) return getCoercedInts(ip, gpa, int, new_ty), }, + .float => |float| switch (ip.indexToKey(new_ty)) { + .simple_type => |simple| switch (simple) { + .f16, + .f32, + .f64, + .f80, + .f128, + .c_longdouble, + .comptime_float, + => return ip.get(gpa, .{ .float = .{ + .ty = new_ty, + .storage = float.storage, + } }), + else => {}, + }, + else => {}, + }, .enum_tag => |enum_tag| if (ip.isIntegerType(new_ty)) return getCoercedInts(ip, gpa, ip.indexToKey(enum_tag.int).int, new_ty), .enum_literal => |enum_literal| switch (ip.indexToKey(new_ty)) { @@ -4688,6 +4707,80 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al .ty = new_ty, .val = error_union.val, } }), + .aggregate => |aggregate| { + const new_len = @intCast(usize, ip.aggregateTypeLen(new_ty)); + direct: { + const old_ty_child = switch (ip.indexToKey(old_ty)) { + inline .array_type, .vector_type => |seq_type| seq_type.child, + .anon_struct_type, .struct_type => break :direct, + else => unreachable, + }; + const new_ty_child = switch (ip.indexToKey(new_ty)) { + inline .array_type, .vector_type => |seq_type| seq_type.child, + .anon_struct_type, .struct_type => break :direct, + else => unreachable, + }; + if (old_ty_child != new_ty_child) break :direct; + // TODO: write something like getCoercedInts to avoid needing to dupe here + switch (aggregate.storage) { + .bytes => |bytes| { + const bytes_copy = try gpa.dupe(u8, bytes[0..new_len]); + defer gpa.free(bytes_copy); + return ip.get(gpa, .{ .aggregate = .{ + .ty = new_ty, + .storage = .{ .bytes = bytes_copy }, + } }); + }, + .elems => |elems| { + const elems_copy = try gpa.dupe(InternPool.Index, elems[0..new_len]); + defer gpa.free(elems_copy); + return ip.get(gpa, .{ .aggregate = .{ + .ty = new_ty, + .storage = .{ .elems = elems_copy }, + } }); + }, + .repeated_elem => |elem| { + return ip.get(gpa, .{ .aggregate = .{ + .ty = new_ty, + .storage = .{ .repeated_elem = elem }, + } }); + }, + } + } + // Direct approach failed - we must recursively coerce elems + const agg_elems = try gpa.alloc(InternPool.Index, new_len); + defer gpa.free(agg_elems); + // First, fill the vector with the uncoerced elements. We do this to avoid key + // lifetime issues, since it'll allow us to avoid referencing `aggregate` after we + // begin interning elems. + switch (aggregate.storage) { + .bytes => { + // We have to intern each value here, so unfortunately we can't easily avoid + // the repeated indexToKey calls. + for (agg_elems, 0..) |*elem, i| { + const x = ip.indexToKey(val).aggregate.storage.bytes[i]; + elem.* = try ip.get(gpa, .{ .int = .{ + .ty = .u8_type, + .storage = .{ .u64 = x }, + } }); + } + }, + .elems => |elems| @memcpy(agg_elems, elems[0..new_len]), + .repeated_elem => |elem| @memset(agg_elems, elem), + } + // Now, coerce each element to its new type. + for (agg_elems, 0..) |*elem, i| { + const new_elem_ty = switch (ip.indexToKey(new_ty)) { + inline .array_type, .vector_type => |seq_type| seq_type.child, + .anon_struct_type => |anon_struct_type| anon_struct_type.types[i], + .struct_type => |struct_type| ip.structPtr(struct_type.index.unwrap().?) + .fields.values()[i].ty.toIntern(), + else => unreachable, + }; + elem.* = try ip.getCoerced(gpa, elem.*, new_elem_ty); + } + return ip.get(gpa, .{ .aggregate = .{ .ty = new_ty, .storage = .{ .elems = agg_elems } } }); + }, else => {}, }, } diff --git a/src/Sema.zig b/src/Sema.zig index 17867d1dd2..f703c6154c 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -23069,7 +23069,7 @@ fn analyzeMinMax( if (std.debug.runtime_safety) { assert(try sema.intFitsInType(val, refined_ty, null)); } - cur_minmax = try sema.coerceInMemory(block, val, orig_ty, refined_ty, src); + cur_minmax = try sema.coerceInMemory(val, refined_ty); } break :refined refined_ty; @@ -26610,7 +26610,7 @@ fn coerceExtra( var in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src); if (in_memory_result == .ok) { if (maybe_inst_val) |val| { - return sema.coerceInMemory(block, val, inst_ty, dest_ty, dest_ty_src); + return sema.coerceInMemory(val, dest_ty); } try sema.requireRuntimeBlock(block, inst_src, null); return block.addBitCast(dest_ty, inst); @@ -27278,89 +27278,12 @@ fn coerceExtra( return sema.failWithOwnedErrorMsg(msg); } -fn coerceValueInMemory( - sema: *Sema, - block: *Block, - val: Value, - src_ty: Type, - dst_ty: Type, - dst_ty_src: LazySrcLoc, -) CompileError!Value { - const mod = sema.mod; - return switch (mod.intern_pool.indexToKey(val.toIntern())) { - .aggregate => |aggregate| { - const dst_ty_key = mod.intern_pool.indexToKey(dst_ty.toIntern()); - const dest_len = try sema.usizeCast( - block, - dst_ty_src, - mod.intern_pool.aggregateTypeLen(dst_ty.toIntern()), - ); - direct: { - const src_ty_child = switch (mod.intern_pool.indexToKey(src_ty.toIntern())) { - inline .array_type, .vector_type => |seq_type| seq_type.child, - .anon_struct_type, .struct_type => break :direct, - else => unreachable, - }; - const dst_ty_child = switch (dst_ty_key) { - inline .array_type, .vector_type => |seq_type| seq_type.child, - .anon_struct_type, .struct_type => break :direct, - else => unreachable, - }; - if (src_ty_child != dst_ty_child) break :direct; - // TODO: write something like getCoercedInts to avoid needing to dupe - return (try mod.intern(.{ .aggregate = .{ - .ty = dst_ty.toIntern(), - .storage = switch (aggregate.storage) { - .bytes => |bytes| .{ .bytes = try sema.arena.dupe(u8, bytes[0..dest_len]) }, - .elems => |elems| .{ .elems = try sema.arena.dupe(InternPool.Index, elems[0..dest_len]) }, - .repeated_elem => |elem| .{ .repeated_elem = elem }, - }, - } })).toValue(); - } - const dest_elems = try sema.arena.alloc(InternPool.Index, dest_len); - for (dest_elems, 0..) |*dest_elem, i| { - const elem_ty = switch (dst_ty_key) { - inline .array_type, .vector_type => |seq_type| seq_type.child, - .anon_struct_type => |anon_struct_type| anon_struct_type.types[i], - .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).? - .fields.values()[i].ty.toIntern(), - else => unreachable, - }; - const cur_val = switch (aggregate.storage) { - .bytes => |bytes| (try mod.intValue(Type.u8, bytes[i])).toIntern(), - .elems => |elems| elems[i], - .repeated_elem => |elem| elem, - }; - dest_elem.* = (try sema.coerceValueInMemory( - block, - cur_val.toValue(), - mod.intern_pool.typeOf(cur_val).toType(), - elem_ty.toType(), - dst_ty_src, - )).toIntern(); - } - return (try mod.intern(.{ .aggregate = .{ - .ty = dst_ty.toIntern(), - .storage = .{ .elems = dest_elems }, - } })).toValue(); - }, - .float => |float| (try mod.intern(.{ .float = .{ - .ty = dst_ty.toIntern(), - .storage = float.storage, - } })).toValue(), - else => try mod.getCoerced(val, dst_ty), - }; -} - fn coerceInMemory( sema: *Sema, - block: *Block, val: Value, - src_ty: Type, dst_ty: Type, - dst_ty_src: LazySrcLoc, ) CompileError!Air.Inst.Ref { - return sema.addConstant(dst_ty, try sema.coerceValueInMemory(block, val, src_ty, dst_ty, dst_ty_src)); + return sema.addConstant(dst_ty, try sema.mod.getCoerced(val, dst_ty)); } const InMemoryCoercionResult = union(enum) { @@ -29820,7 +29743,7 @@ fn coerceArrayLike( if (in_memory_result == .ok) { if (try sema.resolveMaybeUndefVal(inst)) |inst_val| { // These types share the same comptime value representation. - return sema.coerceInMemory(block, inst_val, inst_ty, dest_ty, dest_ty_src); + return sema.coerceInMemory(inst_val, dest_ty); } try sema.requireRuntimeBlock(block, inst_src, null); return block.addBitCast(dest_ty, inst); @@ -31653,40 +31576,12 @@ const PeerResolveStrategy = enum { /// The peers must all be of the same type. exact, - const Reason = struct { - peers: std.DynamicBitSet, - fn reset(r: *Reason) void { - r.peers.setRangeValue(.{ .start = 0, .end = r.peers.capacity() }, false); - } - }; - - fn name(s: PeerResolveStrategy) []const u8 { - return switch (s) { - .unknown, .exact => "exact", - .error_set => "error set", - .error_union => "error union", - .nullable => "null", - .optional => "optional", - .array => "array", - .vector => "vector", - .c_ptr => "C pointer", - .ptr => "pointer", - .func => "function", - .enum_or_union => "enum or union", - .comptime_int => "comptime_int", - .comptime_float => "comptime_float", - .fixed_int => "fixed-width int", - .fixed_float => "fixed-width float", - .coercible_struct => "anonymous struct or tuple", - }; - } - /// Given two strategies, find a strategy that satisfies both, if one exists. If no such /// strategy exists, any strategy may be returned; an error will be emitted when the caller /// attempts to use the strategy to resolve the type. - /// Strategy `a` comes from the peers set in `reason`, while strategy `b` comes from the peer at - /// index `b_peer_idx`. `reason` will be updated to reflect the reason for the new strategy. - fn merge(a: PeerResolveStrategy, b: PeerResolveStrategy, reason: *Reason, b_peer_idx: usize) PeerResolveStrategy { + /// Strategy `a` comes from the peer in `reason_peer`, while strategy `b` comes from the peer at + /// index `b_peer_idx`. `reason_peer` is updated to reflect the reason for the new strategy. + fn merge(a: PeerResolveStrategy, b: PeerResolveStrategy, reason_peer: *usize, b_peer_idx: usize) PeerResolveStrategy { // Our merging should be order-independent. Thus, even though the union order is arbitrary, // by sorting the tags and switching first on the smaller, we have half as many cases to // worry about (since we avoid the duplicates). @@ -31698,14 +31593,13 @@ const PeerResolveStrategy = enum { all_s0, all_s1, either, - both, }; const res: struct { ReasonMethod, PeerResolveStrategy } = switch (s0) { .unknown => .{ .all_s1, s1 }, .error_set => switch (s1) { .error_set => .{ .either, .error_set }, - else => .{ .both, .error_union }, + else => .{ .all_s0, .error_union }, }, .error_union => switch (s1) { .error_union => .{ .either, .error_union }, @@ -31714,7 +31608,7 @@ const PeerResolveStrategy = enum { .nullable => switch (s1) { .nullable => .{ .either, .nullable }, .c_ptr => .{ .all_s1, .c_ptr }, - else => .{ .both, .optional }, + else => .{ .all_s0, .optional }, }, .optional => switch (s1) { .optional => .{ .either, .optional }, @@ -31772,23 +31666,17 @@ const PeerResolveStrategy = enum { switch (res[0]) { .all_s0 => { if (!s0_is_a) { - reason.reset(); - reason.peers.set(b_peer_idx); + reason_peer.* = b_peer_idx; } }, .all_s1 => { if (s0_is_a) { - reason.reset(); - reason.peers.set(b_peer_idx); + reason_peer.* = b_peer_idx; } }, .either => { - // Prefer b, since it's a single peer - reason.reset(); - reason.peers.set(b_peer_idx); - }, - .both => { - reason.peers.set(b_peer_idx); + // Prefer the earliest peer + reason_peer.* = @min(reason_peer.*, b_peer_idx); }, } @@ -31820,12 +31708,7 @@ const PeerResolveStrategy = enum { const PeerResolveResult = union(enum) { /// The peer type resolution was successful, and resulted in the given type. success: Type, - /// The chosen strategy was incompatible with the given peer. - bad_strat: struct { - strat: PeerResolveStrategy, - peer_idx: usize, - }, - /// There was some conflict between two specific peers. + /// There was some generic conflict between two peers. conflict: struct { peer_idx_a: usize, peer_idx_b: usize, @@ -31847,7 +31730,6 @@ const PeerResolveResult = union(enum) { src: LazySrcLoc, instructions: []const Air.Inst.Ref, candidate_srcs: Module.PeerTypeCandidateSrc, - strat_reason: PeerResolveStrategy.Reason, ) !*Module.ErrorMsg { const mod = sema.mod; const decl_ptr = mod.declPtr(block.src_decl); @@ -31867,41 +31749,6 @@ const PeerResolveResult = union(enum) { switch (cur) { .success => unreachable, - .bad_strat => |bad_strat| bad_strat: { - if (strat_reason.peers.count() == 1) { - // We can write this error more simply as a conflict between two peers - conflict_idx = .{ - strat_reason.peers.findFirstSet().?, - bad_strat.peer_idx, - }; - break :bad_strat; - } - - const fmt = "type resolution strategy failed"; - const msg = if (opt_msg) |msg| msg: { - try sema.errNote(block, src, msg, fmt, .{}); - break :msg msg; - } else msg: { - const msg = try sema.errMsg(block, src, fmt, .{}); - opt_msg = msg; - break :msg msg; - }; - - const peer_ty = peer_tys[bad_strat.peer_idx]; - const peer_src = candidate_srcs.resolve(mod, decl_ptr, bad_strat.peer_idx) orelse src; - try sema.errNote(block, peer_src, msg, "strategy '{s}' failed for type '{}' here", .{ bad_strat.strat.name(), peer_ty.fmt(mod) }); - - try sema.errNote(block, src, msg, "strategy chosen using {} peers", .{strat_reason.peers.count()}); - var it = strat_reason.peers.iterator(.{}); - while (it.next()) |strat_peer_idx| { - const strat_peer_ty = peer_tys[strat_peer_idx]; - const strat_peer_src = candidate_srcs.resolve(mod, decl_ptr, strat_peer_idx) orelse src; - try sema.errNote(block, strat_peer_src, msg, "peer of type '{}' here", .{strat_peer_ty.fmt(mod)}); - } - - // No child error - break; - }, .conflict => |conflict| { // Fall through to two-peer conflict handling below conflict_idx = .{ @@ -31925,7 +31772,7 @@ const PeerResolveResult = union(enum) { }, } - // This is the path for reporting a conflict between two peers. + // This is the path for reporting a generic conflict between two peers. if (conflict_idx[1] < conflict_idx[0]) { // b comes first in source, so it's better if it comes first in the error @@ -31987,14 +31834,10 @@ fn resolvePeerTypes( val.* = try sema.resolveMaybeUndefVal(inst); } - var strat_reason: PeerResolveStrategy.Reason = .{ - .peers = try std.DynamicBitSet.initEmpty(sema.arena, instructions.len), - }; - - switch (try sema.resolvePeerTypesInner(block, src, peer_tys, peer_vals, &strat_reason)) { + switch (try sema.resolvePeerTypesInner(block, src, peer_tys, peer_vals)) { .success => |ty| return ty, else => |result| { - const msg = try result.report(sema, block, src, instructions, candidate_srcs, strat_reason); + const msg = try result.report(sema, block, src, instructions, candidate_srcs); return sema.failWithOwnedErrorMsg(msg); }, } @@ -32006,16 +31849,14 @@ fn resolvePeerTypesInner( src: LazySrcLoc, peer_tys: []?Type, peer_vals: []?Value, - strat_reason: *PeerResolveStrategy.Reason, ) !PeerResolveResult { const mod = sema.mod; - strat_reason.reset(); - + var strat_reason: usize = 0; var s: PeerResolveStrategy = .unknown; for (peer_tys, 0..) |opt_ty, i| { const ty = opt_ty orelse continue; - s = s.merge(PeerResolveStrategy.select(ty, mod), strat_reason, i); + s = s.merge(PeerResolveStrategy.select(ty, mod), &strat_reason, i); } if (s == .unknown) { @@ -32041,9 +31882,9 @@ fn resolvePeerTypesInner( var final_set: ?Type = null; for (peer_tys, 0..) |opt_ty, i| { const ty = opt_ty orelse continue; - if (ty.zigTypeTag(mod) != .ErrorSet) return .{ .bad_strat = .{ - .strat = s, - .peer_idx = i, + if (ty.zigTypeTag(mod) != .ErrorSet) return .{ .conflict = .{ + .peer_idx_a = strat_reason, + .peer_idx_b = i, } }; if (final_set) |cur_set| { final_set = try sema.maybeMergeErrorSets(block, src, cur_set, ty); @@ -32091,7 +31932,6 @@ fn resolvePeerTypesInner( src, peer_tys, peer_vals, - strat_reason, )) { .success => |ty| ty, else => |result| return result, @@ -32102,9 +31942,9 @@ fn resolvePeerTypesInner( .nullable => { for (peer_tys, 0..) |opt_ty, i| { const ty = opt_ty orelse continue; - if (!ty.eql(Type.null, mod)) return .{ .bad_strat = .{ - .strat = s, - .peer_idx = i, + if (!ty.eql(Type.null, mod)) return .{ .conflict = .{ + .peer_idx_a = strat_reason, + .peer_idx_b = i, } }; } return .{ .success = Type.null }; @@ -32130,7 +31970,6 @@ fn resolvePeerTypesInner( src, peer_tys, peer_vals, - strat_reason, )) { .success => |ty| ty, else => |result| return result, @@ -32154,9 +31993,9 @@ fn resolvePeerTypesInner( if (!ty.isArrayOrVector(mod)) { // We allow tuples of the correct length. We won't validate their elem type, since the elements can be coerced. - const arr_like = sema.typeIsArrayLike(ty) orelse return .{ .bad_strat = .{ - .strat = s, - .peer_idx = i, + const arr_like = sema.typeIsArrayLike(ty) orelse return .{ .conflict = .{ + .peer_idx_a = strat_reason, + .peer_idx_b = i, } }; if (opt_first_idx) |first_idx| { @@ -32224,9 +32063,9 @@ fn resolvePeerTypesInner( if (!ty.isArrayOrVector(mod)) { // Allow tuples of the correct length - const arr_like = sema.typeIsArrayLike(ty) orelse return .{ .bad_strat = .{ - .strat = s, - .peer_idx = i, + const arr_like = sema.typeIsArrayLike(ty) orelse return .{ .conflict = .{ + .peer_idx_a = strat_reason, + .peer_idx_b = i, } }; if (len) |expect_len| { @@ -32266,7 +32105,6 @@ fn resolvePeerTypesInner( src, peer_tys, peer_vals, - strat_reason, )) { .success => |ty| ty, else => |result| return result, @@ -32300,9 +32138,9 @@ fn resolvePeerTypesInner( else => {}, } - if (!ty.isPtrAtRuntime(mod)) return .{ .bad_strat = .{ - .strat = s, - .peer_idx = i, + if (!ty.isPtrAtRuntime(mod)) return .{ .conflict = .{ + .peer_idx_a = strat_reason, + .peer_idx_b = i, } }; // Goes through optionals @@ -32316,7 +32154,6 @@ fn resolvePeerTypesInner( }; // Try peer -> cur, then cur -> peer - const old_pointee_type = ptr_info.pointee_type; ptr_info.pointee_type = (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) orelse { return .{ .conflict = .{ .peer_idx_a = first_idx, @@ -32325,8 +32162,8 @@ fn resolvePeerTypesInner( }; if (ptr_info.sentinel != null and peer_info.sentinel != null) { - const peer_sent = try sema.coerceValueInMemory(block, ptr_info.sentinel.?, old_pointee_type, ptr_info.pointee_type, .unneeded); - const ptr_sent = try sema.coerceValueInMemory(block, peer_info.sentinel.?, peer_info.pointee_type, ptr_info.pointee_type, .unneeded); + const peer_sent = try mod.getCoerced(ptr_info.sentinel.?, ptr_info.pointee_type); + const ptr_sent = try mod.getCoerced(peer_info.sentinel.?, ptr_info.pointee_type); if (ptr_sent.eql(peer_sent, ptr_info.pointee_type, mod)) { ptr_info.sentinel = ptr_sent; } else { @@ -32379,18 +32216,18 @@ fn resolvePeerTypesInner( .pointee_type = ty, .@"addrspace" = target_util.defaultAddressSpace(target, .global_constant), }, - else => return .{ .bad_strat = .{ - .strat = s, - .peer_idx = i, + else => return .{ .conflict = .{ + .peer_idx_a = strat_reason, + .peer_idx_b = i, } }, }; switch (peer_info.size) { .One, .Many => {}, .Slice => opt_slice_idx = i, - .C => return .{ .bad_strat = .{ - .strat = s, - .peer_idx = i, + .C => return .{ .conflict = .{ + .peer_idx_a = strat_reason, + .peer_idx_b = i, } }, } @@ -32605,10 +32442,8 @@ fn resolvePeerTypesInner( no_sentinel: { if (peer_sentinel == null) break :no_sentinel; if (cur_sentinel == null) break :no_sentinel; - const peer_sent_ty = mod.intern_pool.typeOf(peer_sentinel.?.toIntern()).toType(); - const cur_sent_ty = mod.intern_pool.typeOf(cur_sentinel.?.toIntern()).toType(); - const peer_sent_coerced = try sema.coerceValueInMemory(block, peer_sentinel.?, peer_sent_ty, sentinel_ty, .unneeded); - const cur_sent_coerced = try sema.coerceValueInMemory(block, cur_sentinel.?, cur_sent_ty, sentinel_ty, .unneeded); + const peer_sent_coerced = try mod.getCoerced(peer_sentinel.?, sentinel_ty); + const cur_sent_coerced = try mod.getCoerced(cur_sentinel.?, sentinel_ty); if (!peer_sent_coerced.eql(cur_sent_coerced, sentinel_ty, mod)) break :no_sentinel; // Sentinels match if (ptr_info.size == .One) { @@ -32664,9 +32499,9 @@ fn resolvePeerTypesInner( first_idx = i; continue; }; - if (ty.zigTypeTag(mod) != .Fn) return .{ .bad_strat = .{ - .strat = s, - .peer_idx = i, + if (ty.zigTypeTag(mod) != .Fn) return .{ .conflict = .{ + .peer_idx_a = strat_reason, + .peer_idx_b = i, } }; // ty -> cur_ty if (.ok == try sema.coerceInMemoryAllowedFns(block, cur_ty, ty, target, src, src)) { @@ -32694,9 +32529,9 @@ fn resolvePeerTypesInner( const ty = opt_ty orelse continue; switch (ty.zigTypeTag(mod)) { .EnumLiteral, .Enum, .Union => {}, - else => return .{ .bad_strat = .{ - .strat = s, - .peer_idx = i, + else => return .{ .conflict = .{ + .peer_idx_a = strat_reason, + .peer_idx_b = i, } }, } const cur_ty = opt_cur_ty orelse { @@ -32751,9 +32586,9 @@ fn resolvePeerTypesInner( const ty = opt_ty orelse continue; switch (ty.zigTypeTag(mod)) { .ComptimeInt => {}, - else => return .{ .bad_strat = .{ - .strat = s, - .peer_idx = i, + else => return .{ .conflict = .{ + .peer_idx_a = strat_reason, + .peer_idx_b = i, } }, } } @@ -32765,9 +32600,9 @@ fn resolvePeerTypesInner( const ty = opt_ty orelse continue; switch (ty.zigTypeTag(mod)) { .ComptimeInt, .ComptimeFloat => {}, - else => return .{ .bad_strat = .{ - .strat = s, - .peer_idx = i, + else => return .{ .conflict = .{ + .peer_idx_a = strat_reason, + .peer_idx_b = i, } }, } } @@ -32789,18 +32624,18 @@ fn resolvePeerTypesInner( switch (peer_tag) { .ComptimeInt => { // If the value is undefined, we can't refine to a fixed-width int - if (opt_val == null or opt_val.?.isUndef(mod)) return .{ .bad_strat = .{ - .strat = s, - .peer_idx = i, + if (opt_val == null or opt_val.?.isUndef(mod)) return .{ .conflict = .{ + .peer_idx_a = strat_reason, + .peer_idx_b = i, } }; any_comptime_known = true; ptr_opt_val.* = try sema.resolveLazyValue(opt_val.?); continue; }, .Int => {}, - else => return .{ .bad_strat = .{ - .strat = s, - .peer_idx = i, + else => return .{ .conflict = .{ + .peer_idx_a = strat_reason, + .peer_idx_b = i, } }, } @@ -32868,9 +32703,9 @@ fn resolvePeerTypesInner( switch (ty.zigTypeTag(mod)) { .ComptimeFloat, .ComptimeInt => {}, .Int => { - if (opt_val == null) return .{ .bad_strat = .{ - .strat = s, - .peer_idx = i, + if (opt_val == null) return .{ .conflict = .{ + .peer_idx_a = strat_reason, + .peer_idx_b = i, } }; }, .Float => { @@ -32890,9 +32725,9 @@ fn resolvePeerTypesInner( opt_cur_ty = ty; } }, - else => return .{ .bad_strat = .{ - .strat = s, - .peer_idx = i, + else => return .{ .conflict = .{ + .peer_idx_a = strat_reason, + .peer_idx_b = i, } }, } } @@ -32915,9 +32750,9 @@ fn resolvePeerTypesInner( const ty = opt_ty orelse continue; if (!ty.isTupleOrAnonStruct(mod)) { - return .{ .bad_strat = .{ - .strat = s, - .peer_idx = i, + return .{ .conflict = .{ + .peer_idx_a = strat_reason, + .peer_idx_b = i, } }; } @@ -32973,7 +32808,7 @@ fn resolvePeerTypesInner( } // Resolve field type recursively - field_ty.* = switch (try sema.resolvePeerTypesInner(block, src, sub_peer_tys, sub_peer_vals, strat_reason)) { + field_ty.* = switch (try sema.resolvePeerTypesInner(block, src, sub_peer_tys, sub_peer_vals)) { .success => |ty| ty.toIntern(), else => |result| { const result_buf = try sema.arena.create(PeerResolveResult); @@ -35538,7 +35373,7 @@ fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value // Move mutable decl values to the InternPool and assert other decls are already in // the InternPool. const uncoerced_val = if (deref.is_mutable) try tv.val.intern(tv.ty, mod) else tv.val.toIntern(); - const coerced_val = try sema.coerceValueInMemory(block, uncoerced_val.toValue(), tv.ty, load_ty, src); + const coerced_val = try mod.getCoerced(uncoerced_val.toValue(), load_ty); return .{ .val = coerced_val }; } } |
