| ... | ... | @@ -3659,7 +3659,10 @@ fn validateStructInit( |
| 3659 | 3659 | const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data; |
| 3660 | 3660 | struct_ptr_zir_ref = field_ptr_extra.lhs; |
| 3661 | 3661 | const field_name = sema.code.nullTerminatedString(field_ptr_extra.field_name_start); |
| 3662 | | const field_index = try sema.structFieldIndex(block, struct_ty, field_name, field_src); |
| 3662 | const field_index = if (struct_ty.isTuple()) |
| 3663 | try sema.tupleFieldIndex(block, struct_ty, field_name, field_src) |
| 3664 | else |
| 3665 | try sema.structFieldIndex(block, struct_ty, field_name, field_src); |
| 3663 | 3666 | if (found_fields[field_index] != 0) { |
| 3664 | 3667 | const other_field_ptr = found_fields[field_index]; |
| 3665 | 3668 | const other_field_ptr_data = sema.code.instructions.items(.data)[other_field_ptr].pl_node; |
| ... | ... | @@ -3701,7 +3704,7 @@ fn validateStructInit( |
| 3701 | 3704 | } |
| 3702 | 3705 | |
| 3703 | 3706 | const field_src = init_src; // TODO better source location |
| 3704 | | const default_field_ptr = try sema.structFieldPtrByIndex(block, init_src, struct_ptr, @intCast(u32, i), field_src, struct_ty); |
| 3707 | const default_field_ptr = try sema.structFieldPtrByIndex(block, init_src, struct_ptr, @intCast(u32, i), field_src, struct_ty, true); |
| 3705 | 3708 | const field_ty = sema.typeOf(default_field_ptr).childType(); |
| 3706 | 3709 | const init = try sema.addConstant(field_ty, default_val); |
| 3707 | 3710 | try sema.storePtr2(block, init_src, default_field_ptr, init_src, init, field_src, .store); |
| ... | ... | @@ -3859,7 +3862,7 @@ fn validateStructInit( |
| 3859 | 3862 | if (field_ptr != 0) continue; |
| 3860 | 3863 | |
| 3861 | 3864 | const field_src = init_src; // TODO better source location |
| 3862 | | const default_field_ptr = try sema.structFieldPtrByIndex(block, init_src, struct_ptr, @intCast(u32, i), field_src, struct_ty); |
| 3865 | const default_field_ptr = try sema.structFieldPtrByIndex(block, init_src, struct_ptr, @intCast(u32, i), field_src, struct_ty, true); |
| 3863 | 3866 | const field_ty = sema.typeOf(default_field_ptr).childType(); |
| 3864 | 3867 | const init = try sema.addConstant(field_ty, field_values[i]); |
| 3865 | 3868 | try sema.storePtr2(block, init_src, default_field_ptr, init_src, init, field_src, .store); |
| ... | ... | @@ -14494,7 +14497,10 @@ fn zirStructInit( |
| 14494 | 14497 | const field_src: LazySrcLoc = .{ .node_offset_initializer = field_type_data.src_node }; |
| 14495 | 14498 | const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data; |
| 14496 | 14499 | const field_name = sema.code.nullTerminatedString(field_type_extra.name_start); |
| 14497 | | const field_index = try sema.structFieldIndex(block, resolved_ty, field_name, field_src); |
| 14500 | const field_index = if (resolved_ty.isTuple()) |
| 14501 | try sema.tupleFieldIndex(block, resolved_ty, field_name, field_src) |
| 14502 | else |
| 14503 | try sema.structFieldIndex(block, resolved_ty, field_name, field_src); |
| 14498 | 14504 | if (field_inits[field_index] != .none) { |
| 14499 | 14505 | const other_field_type = found_fields[field_index]; |
| 14500 | 14506 | const other_field_type_data = zir_datas[other_field_type].pl_node; |
| ... | ... | @@ -14649,7 +14655,7 @@ fn finishStructInit( |
| 14649 | 14655 | for (field_inits) |field_init, i_usize| { |
| 14650 | 14656 | const i = @intCast(u32, i_usize); |
| 14651 | 14657 | const field_src = dest_src; |
| 14652 | | const field_ptr = try sema.structFieldPtrByIndex(block, dest_src, alloc, i, field_src, struct_ty); |
| 14658 | const field_ptr = try sema.structFieldPtrByIndex(block, dest_src, alloc, i, field_src, struct_ty, true); |
| 14653 | 14659 | try sema.storePtr(block, dest_src, field_ptr, field_init); |
| 14654 | 14660 | } |
| 14655 | 14661 | |
| ... | ... | @@ -19398,7 +19404,7 @@ fn fieldVal( |
| 19398 | 19404 | }, |
| 19399 | 19405 | .Struct => if (is_pointer_to) { |
| 19400 | 19406 | // Avoid loading the entire struct by fetching a pointer and loading that |
| 19401 | | const field_ptr = try sema.structFieldPtr(block, src, object, field_name, field_name_src, inner_ty); |
| 19407 | const field_ptr = try sema.structFieldPtr(block, src, object, field_name, field_name_src, inner_ty, false); |
| 19402 | 19408 | return sema.analyzeLoad(block, src, field_ptr, object_src); |
| 19403 | 19409 | } else { |
| 19404 | 19410 | return sema.structFieldVal(block, src, object, field_name, field_name_src, inner_ty); |
| ... | ... | @@ -19607,7 +19613,7 @@ fn fieldPtr( |
| 19607 | 19613 | try sema.analyzeLoad(block, src, object_ptr, object_ptr_src) |
| 19608 | 19614 | else |
| 19609 | 19615 | object_ptr; |
| 19610 | | return sema.structFieldPtr(block, src, inner_ptr, field_name, field_name_src, inner_ty); |
| 19616 | return sema.structFieldPtr(block, src, inner_ptr, field_name, field_name_src, inner_ty, initializing); |
| 19611 | 19617 | }, |
| 19612 | 19618 | .Union => { |
| 19613 | 19619 | const inner_ptr = if (is_pointer_to) |
| ... | ... | @@ -19816,6 +19822,7 @@ fn structFieldPtr( |
| 19816 | 19822 | field_name: []const u8, |
| 19817 | 19823 | field_name_src: LazySrcLoc, |
| 19818 | 19824 | unresolved_struct_ty: Type, |
| 19825 | initializing: bool, |
| 19819 | 19826 | ) CompileError!Air.Inst.Ref { |
| 19820 | 19827 | assert(unresolved_struct_ty.zigTypeTag() == .Struct); |
| 19821 | 19828 | |
| ... | ... | @@ -19828,10 +19835,10 @@ fn structFieldPtr( |
| 19828 | 19835 | return sema.analyzeRef(block, src, len_inst); |
| 19829 | 19836 | } |
| 19830 | 19837 | const field_index = try sema.tupleFieldIndex(block, struct_ty, field_name, field_name_src); |
| 19831 | | return sema.tupleFieldPtr(block, src, struct_ptr, field_name_src, field_index); |
| 19838 | return sema.tupleFieldPtr(block, src, struct_ptr, field_name_src, field_index, initializing); |
| 19832 | 19839 | } else if (struct_ty.isAnonStruct()) { |
| 19833 | 19840 | const field_index = try sema.anonStructFieldIndex(block, struct_ty, field_name, field_name_src); |
| 19834 | | return sema.tupleFieldPtr(block, src, struct_ptr, field_name_src, field_index); |
| 19841 | return sema.tupleFieldPtr(block, src, struct_ptr, field_name_src, field_index, initializing); |
| 19835 | 19842 | } |
| 19836 | 19843 | |
| 19837 | 19844 | const struct_obj = struct_ty.castTag(.@"struct").?.data; |
| ... | ... | @@ -19840,7 +19847,7 @@ fn structFieldPtr( |
| 19840 | 19847 | return sema.failWithBadStructFieldAccess(block, struct_obj, field_name_src, field_name); |
| 19841 | 19848 | const field_index = @intCast(u32, field_index_big); |
| 19842 | 19849 | |
| 19843 | | return sema.structFieldPtrByIndex(block, src, struct_ptr, field_index, field_name_src, struct_ty); |
| 19850 | return sema.structFieldPtrByIndex(block, src, struct_ptr, field_index, field_name_src, struct_ty, initializing); |
| 19844 | 19851 | } |
| 19845 | 19852 | |
| 19846 | 19853 | fn structFieldPtrByIndex( |
| ... | ... | @@ -19851,9 +19858,10 @@ fn structFieldPtrByIndex( |
| 19851 | 19858 | field_index: u32, |
| 19852 | 19859 | field_src: LazySrcLoc, |
| 19853 | 19860 | struct_ty: Type, |
| 19861 | initializing: bool, |
| 19854 | 19862 | ) CompileError!Air.Inst.Ref { |
| 19855 | 19863 | if (struct_ty.isAnonStruct()) { |
| 19856 | | return sema.tupleFieldPtr(block, src, struct_ptr, field_src, field_index); |
| 19864 | return sema.tupleFieldPtr(block, src, struct_ptr, field_src, field_index, initializing); |
| 19857 | 19865 | } |
| 19858 | 19866 | |
| 19859 | 19867 | const struct_obj = struct_ty.castTag(.@"struct").?.data; |
| ... | ... | @@ -20050,6 +20058,10 @@ fn tupleFieldValByIndex( |
| 20050 | 20058 | return sema.addConstant(field_ty, field_values[field_index]); |
| 20051 | 20059 | } |
| 20052 | 20060 | |
| 20061 | if (tuple_ty.structFieldValueComptime(field_index)) |default_val| { |
| 20062 | return sema.addConstant(field_ty, default_val); |
| 20063 | } |
| 20064 | |
| 20053 | 20065 | try sema.requireRuntimeBlock(block, src, null); |
| 20054 | 20066 | return block.addStructFieldVal(tuple_byval, field_index, field_ty); |
| 20055 | 20067 | } |
| ... | ... | @@ -20250,7 +20262,7 @@ fn elemPtr( |
| 20250 | 20262 | // Tuple field access. |
| 20251 | 20263 | const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index, "tuple field access index must be comptime known"); |
| 20252 | 20264 | const index = @intCast(u32, index_val.toUnsignedInt(target)); |
| 20253 | | return sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index); |
| 20265 | return sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index, init); |
| 20254 | 20266 | }, |
| 20255 | 20267 | else => unreachable, |
| 20256 | 20268 | } |
| ... | ... | @@ -20353,6 +20365,7 @@ fn tupleFieldPtr( |
| 20353 | 20365 | tuple_ptr: Air.Inst.Ref, |
| 20354 | 20366 | field_index_src: LazySrcLoc, |
| 20355 | 20367 | field_index: u32, |
| 20368 | init: bool, |
| 20356 | 20369 | ) CompileError!Air.Inst.Ref { |
| 20357 | 20370 | const tuple_ptr_ty = sema.typeOf(tuple_ptr); |
| 20358 | 20371 | const tuple_ty = tuple_ptr_ty.childType(); |
| ... | ... | @@ -20386,7 +20399,17 @@ fn tupleFieldPtr( |
| 20386 | 20399 | ); |
| 20387 | 20400 | } |
| 20388 | 20401 | |
| 20389 | | try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_ptr_src); |
| 20402 | if (tuple_ty.structFieldValueComptime(field_index)) |default_val| { |
| 20403 | const val = try Value.Tag.comptime_field_ptr.create(sema.arena, .{ |
| 20404 | .field_ty = field_ty, |
| 20405 | .field_val = default_val, |
| 20406 | }); |
| 20407 | return sema.addConstant(ptr_field_ty, val); |
| 20408 | } |
| 20409 | |
| 20410 | if (!init) { |
| 20411 | try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_ptr_src); |
| 20412 | } |
| 20390 | 20413 | |
| 20391 | 20414 | try sema.requireRuntimeBlock(block, tuple_ptr_src, null); |
| 20392 | 20415 | return block.addStructFieldPtr(tuple_ptr, field_index, ptr_field_ty); |