@@ -30053,8 +30053,8 @@ fn coerceExtra(
30053
30053
else => {},
30054
30054
},
30055
30055
.@"struct" => blk: {
30056
- if (inst_ty.isTuple(zcu)) {
30057
- return sema.coerceTupleToStruct (block, dest_ty, inst, inst_src) catch |err| switch (err) {
30056
+ if (dest_ty.isTuple(zcu) and inst_ty.isTuple(zcu)) {
30057
+ return sema.coerceTupleToTuple (block, dest_ty, inst, inst_src) catch |err| switch (err) {
30058
30058
error.NotCoercible => break :blk,
30059
30059
else => |e| return e,
30060
30060
};
@@ -32135,114 +32135,6 @@ fn coerceTupleToArrayPtrs(
32135
32135
return ptr_array;
32136
32136
}
32137
32137
32138
- /// Handles both tuples and anon struct literals. Coerces field-wise. Reports
32139
- /// errors for both extra fields and missing fields.
32140
- fn coerceTupleToStruct(
32141
- sema: *Sema,
32142
- block: *Block,
32143
- struct_ty: Type,
32144
- inst: Air.Inst.Ref,
32145
- inst_src: LazySrcLoc,
32146
- ) !Air.Inst.Ref {
32147
- const pt = sema.pt;
32148
- const zcu = pt.zcu;
32149
- const ip = &zcu.intern_pool;
32150
- try struct_ty.resolveFields(pt);
32151
- try struct_ty.resolveStructFieldInits(pt);
32152
-
32153
- if (struct_ty.isTuple(zcu)) {
32154
- return sema.coerceTupleToTuple(block, struct_ty, inst, inst_src);
32155
- }
32156
-
32157
- const struct_type = zcu.typeToStruct(struct_ty).?;
32158
- const field_vals = try sema.arena.alloc(InternPool.Index, struct_type.field_types.len);
32159
- const field_refs = try sema.arena.alloc(Air.Inst.Ref, field_vals.len);
32160
- @memset(field_refs, .none);
32161
-
32162
- const inst_ty = sema.typeOf(inst);
32163
- var runtime_src: ?LazySrcLoc = null;
32164
- const field_count = switch (ip.indexToKey(inst_ty.toIntern())) {
32165
- .tuple_type => |tuple| tuple.types.len,
32166
- .struct_type => ip.loadStructType(inst_ty.toIntern()).field_types.len,
32167
- else => unreachable,
32168
- };
32169
- for (0..field_count) |tuple_field_index| {
32170
- const field_src = inst_src; // TODO better source location
32171
- const field_name = inst_ty.structFieldName(tuple_field_index, zcu).unwrap() orelse
32172
- try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{d}", .{tuple_field_index}, .no_embedded_nulls);
32173
-
32174
- const struct_field_index = try sema.structFieldIndex(block, struct_ty, field_name, field_src);
32175
- const struct_field_ty = Type.fromInterned(struct_type.field_types.get(ip)[struct_field_index]);
32176
- const elem_ref = try sema.tupleField(block, inst_src, inst, field_src, @intCast(tuple_field_index));
32177
- const coerced = try sema.coerce(block, struct_field_ty, elem_ref, field_src);
32178
- field_refs[struct_field_index] = coerced;
32179
- if (struct_type.fieldIsComptime(ip, struct_field_index)) {
32180
- const init_val = try sema.resolveValue(coerced) orelse {
32181
- return sema.failWithNeededComptime(block, field_src, .{ .simple = .stored_to_comptime_field });
32182
- };
32183
-
32184
- const field_init = Value.fromInterned(struct_type.field_inits.get(ip)[struct_field_index]);
32185
- if (!init_val.eql(field_init, struct_field_ty, pt.zcu)) {
32186
- return sema.failWithInvalidComptimeFieldStore(block, field_src, inst_ty, tuple_field_index);
32187
- }
32188
- }
32189
- if (runtime_src == null) {
32190
- if (try sema.resolveValue(coerced)) |field_val| {
32191
- field_vals[struct_field_index] = field_val.toIntern();
32192
- } else {
32193
- runtime_src = field_src;
32194
- }
32195
- }
32196
- }
32197
-
32198
- // Populate default field values and report errors for missing fields.
32199
- var root_msg: ?*Zcu.ErrorMsg = null;
32200
- errdefer if (root_msg) |msg| msg.destroy(sema.gpa);
32201
-
32202
- for (field_refs, 0..) |*field_ref, i| {
32203
- if (field_ref.* != .none) continue;
32204
-
32205
- const field_name = struct_type.field_names.get(ip)[i];
32206
- const field_default_val = struct_type.fieldInit(ip, i);
32207
- const field_src = inst_src; // TODO better source location
32208
- if (field_default_val == .none) {
32209
- const template = "missing struct field: {}";
32210
- const args = .{field_name.fmt(ip)};
32211
- if (root_msg) |msg| {
32212
- try sema.errNote(field_src, msg, template, args);
32213
- } else {
32214
- root_msg = try sema.errMsg(field_src, template, args);
32215
- }
32216
- continue;
32217
- }
32218
- if (runtime_src == null) {
32219
- field_vals[i] = field_default_val;
32220
- } else {
32221
- field_ref.* = Air.internedToRef(field_default_val);
32222
- }
32223
- }
32224
-
32225
- if (root_msg) |msg| {
32226
- try sema.addDeclaredHereNote(msg, struct_ty);
32227
- root_msg = null;
32228
- return sema.failWithOwnedErrorMsg(block, msg);
32229
- }
32230
-
32231
- if (runtime_src) |rs| {
32232
- try sema.requireRuntimeBlock(block, inst_src, rs);
32233
- return block.addAggregateInit(struct_ty, field_refs);
32234
- }
32235
-
32236
- const struct_val = try pt.intern(.{ .aggregate = .{
32237
- .ty = struct_ty.toIntern(),
32238
- .storage = .{ .elems = field_vals },
32239
- } });
32240
- // TODO: figure out InternPool removals for incremental compilation
32241
- //errdefer ip.remove(struct_val);
32242
-
32243
- return Air.internedToRef(struct_val);
32244
- }
32245
-
32246
32138
fn coerceTupleToTuple(
32247
32139
sema: *Sema,
32248
32140
block: *Block,
0 commit comments