@@ -3922,7 +3922,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
3922
3922
const store_inst = sema.air_instructions.get(@intFromEnum(store_inst_idx));
3923
3923
const ptr_to_map = switch (store_inst.tag) {
3924
3924
.store, .store_safe => store_inst.data.bin_op.lhs.toIndex().?, // Map the pointer being stored to.
3925
- .set_union_tag => continue, // We can completely ignore these: we'll do it implicitly when we get the field pointer.
3925
+ .set_union_tag => continue, // Ignore for now; handled after we map pointers
3926
3926
.optional_payload_ptr_set, .errunion_payload_ptr_set => store_inst_idx, // Map the generated pointer itself.
3927
3927
else => unreachable,
3928
3928
};
@@ -4055,19 +4055,33 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
4055
4055
}
4056
4056
4057
4057
// We have a correlation between AIR pointers and decl pointers. Perform all stores at comptime.
4058
- // Any implicit stores performed by `optional_payload_ptr_set`, `errunion_payload_ptr_set`, or
4059
- // `set_union_tag` instructions were already done above.
4058
+ // Any implicit stores performed by `optional_payload_ptr_set` or `errunion_payload_ptr_set`
4059
+ // instructions were already done above.
4060
4060
4061
4061
for (stores) |store_inst_idx| {
4062
4062
const store_inst = sema.air_instructions.get(@intFromEnum(store_inst_idx));
4063
4063
switch (store_inst.tag) {
4064
- .set_union_tag => {}, // Handled implicitly by field pointers above
4065
4064
.optional_payload_ptr_set, .errunion_payload_ptr_set => {}, // Handled explicitly above
4065
+ .set_union_tag => {
4066
+ // Usually, we can ignore these, because the creation of the field pointer above
4067
+ // already did it for us. However, if the field is OPV, this is relevant, because
4068
+ // there is not going to be a store to the field. So we must initialize the union
4069
+ // tag if the field is OPV.
4070
+ const union_ptr_inst = store_inst.data.bin_op.lhs.toIndex().?;
4071
+ const union_ptr_val: Value = .fromInterned(ptr_mapping.get(union_ptr_inst).?);
4072
+ const tag_val: Value = .fromInterned(store_inst.data.bin_op.rhs.toInterned().?);
4073
+ const union_ty = union_ptr_val.typeOf(zcu).childType(zcu);
4074
+ const field_ty = union_ty.unionFieldType(tag_val, zcu).?;
4075
+ if (try sema.typeHasOnePossibleValue(field_ty)) |payload_val| {
4076
+ const new_union_val = try pt.unionValue(union_ty, tag_val, payload_val);
4077
+ try sema.storePtrVal(block, .unneeded, union_ptr_val, new_union_val, union_ty);
4078
+ }
4079
+ },
4066
4080
.store, .store_safe => {
4067
4081
const air_ptr_inst = store_inst.data.bin_op.lhs.toIndex().?;
4068
4082
const store_val = (try sema.resolveValue(store_inst.data.bin_op.rhs)).?;
4069
4083
const new_ptr = ptr_mapping.get(air_ptr_inst).?;
4070
- try sema.storePtrVal(block, LazySrcLoc .unneeded, Value .fromInterned(new_ptr), store_val, .fromInterned(zcu.intern_pool. typeOf(store_val.toIntern()) ));
4084
+ try sema.storePtrVal(block, .unneeded, .fromInterned(new_ptr), store_val, store_val. typeOf(zcu ));
4071
4085
},
4072
4086
else => unreachable,
4073
4087
}
0 commit comments