| ... | @@ -3659,7 +3659,10 @@ fn validateStructInit( | ... | @@ -3659,7 +3659,10 @@ fn validateStructInit( |
| 3659 | const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data; | 3659 | const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data; |
| 3660 | struct_ptr_zir_ref = field_ptr_extra.lhs; | 3660 | struct_ptr_zir_ref = field_ptr_extra.lhs; |
| 3661 | const field_name = sema.code.nullTerminatedString(field_ptr_extra.field_name_start); | 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 | if (found_fields[field_index] != 0) { | 3666 | if (found_fields[field_index] != 0) { |
| 3664 | const other_field_ptr = found_fields[field_index]; | 3667 | const other_field_ptr = found_fields[field_index]; |
| 3665 | const other_field_ptr_data = sema.code.instructions.items(.data)[other_field_ptr].pl_node; | 3668 | const other_field_ptr_data = sema.code.instructions.items(.data)[other_field_ptr].pl_node; |
| ... | @@ -3701,7 +3704,7 @@ fn validateStructInit( | ... | @@ -3701,7 +3704,7 @@ fn validateStructInit( |
| 3701 | } | 3704 | } |
| 3702 | | 3705 | |
| 3703 | const field_src = init_src; // TODO better source location | 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 | const field_ty = sema.typeOf(default_field_ptr).childType(); | 3708 | const field_ty = sema.typeOf(default_field_ptr).childType(); |
| 3706 | const init = try sema.addConstant(field_ty, default_val); | 3709 | const init = try sema.addConstant(field_ty, default_val); |
| 3707 | try sema.storePtr2(block, init_src, default_field_ptr, init_src, init, field_src, .store); | 3710 | try sema.storePtr2(block, init_src, default_field_ptr, init_src, init, field_src, .store); |
| ... | @@ -3859,7 +3862,7 @@ fn validateStructInit( | ... | @@ -3859,7 +3862,7 @@ fn validateStructInit( |
| 3859 | if (field_ptr != 0) continue; | 3862 | if (field_ptr != 0) continue; |
| 3860 | | 3863 | |
| 3861 | const field_src = init_src; // TODO better source location | 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 | const field_ty = sema.typeOf(default_field_ptr).childType(); | 3866 | const field_ty = sema.typeOf(default_field_ptr).childType(); |
| 3864 | const init = try sema.addConstant(field_ty, field_values[i]); | 3867 | const init = try sema.addConstant(field_ty, field_values[i]); |
| 3865 | try sema.storePtr2(block, init_src, default_field_ptr, init_src, init, field_src, .store); | 3868 | try sema.storePtr2(block, init_src, default_field_ptr, init_src, init, field_src, .store); |
| ... | @@ -14494,7 +14497,10 @@ fn zirStructInit( | ... | @@ -14494,7 +14497,10 @@ fn zirStructInit( |
| 14494 | const field_src: LazySrcLoc = .{ .node_offset_initializer = field_type_data.src_node }; | 14497 | const field_src: LazySrcLoc = .{ .node_offset_initializer = field_type_data.src_node }; |
| 14495 | const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data; | 14498 | const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data; |
| 14496 | const field_name = sema.code.nullTerminatedString(field_type_extra.name_start); | 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 | if (field_inits[field_index] != .none) { | 14504 | if (field_inits[field_index] != .none) { |
| 14499 | const other_field_type = found_fields[field_index]; | 14505 | const other_field_type = found_fields[field_index]; |
| 14500 | const other_field_type_data = zir_datas[other_field_type].pl_node; | 14506 | const other_field_type_data = zir_datas[other_field_type].pl_node; |
| ... | @@ -14649,7 +14655,7 @@ fn finishStructInit( | ... | @@ -14649,7 +14655,7 @@ fn finishStructInit( |
| 14649 | for (field_inits) |field_init, i_usize| { | 14655 | for (field_inits) |field_init, i_usize| { |
| 14650 | const i = @intCast(u32, i_usize); | 14656 | const i = @intCast(u32, i_usize); |
| 14651 | const field_src = dest_src; | 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 | try sema.storePtr(block, dest_src, field_ptr, field_init); | 14659 | try sema.storePtr(block, dest_src, field_ptr, field_init); |
| 14654 | } | 14660 | } |
| 14655 | | 14661 | |
| ... | @@ -19398,7 +19404,7 @@ fn fieldVal( | ... | @@ -19398,7 +19404,7 @@ fn fieldVal( |
| 19398 | }, | 19404 | }, |
| 19399 | .Struct => if (is_pointer_to) { | 19405 | .Struct => if (is_pointer_to) { |
| 19400 | // Avoid loading the entire struct by fetching a pointer and loading that | 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 | return sema.analyzeLoad(block, src, field_ptr, object_src); | 19408 | return sema.analyzeLoad(block, src, field_ptr, object_src); |
| 19403 | } else { | 19409 | } else { |
| 19404 | return sema.structFieldVal(block, src, object, field_name, field_name_src, inner_ty); | 19410 | return sema.structFieldVal(block, src, object, field_name, field_name_src, inner_ty); |
| ... | @@ -19607,7 +19613,7 @@ fn fieldPtr( | ... | @@ -19607,7 +19613,7 @@ fn fieldPtr( |
| 19607 | try sema.analyzeLoad(block, src, object_ptr, object_ptr_src) | 19613 | try sema.analyzeLoad(block, src, object_ptr, object_ptr_src) |
| 19608 | else | 19614 | else |
| 19609 | object_ptr; | 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 | .Union => { | 19618 | .Union => { |
| 19613 | const inner_ptr = if (is_pointer_to) | 19619 | const inner_ptr = if (is_pointer_to) |
| ... | @@ -19816,6 +19822,7 @@ fn structFieldPtr( | ... | @@ -19816,6 +19822,7 @@ fn structFieldPtr( |
| 19816 | field_name: []const u8, | 19822 | field_name: []const u8, |
| 19817 | field_name_src: LazySrcLoc, | 19823 | field_name_src: LazySrcLoc, |
| 19818 | unresolved_struct_ty: Type, | 19824 | unresolved_struct_ty: Type, |
| | 19825 | initializing: bool, |
| 19819 | ) CompileError!Air.Inst.Ref { | 19826 | ) CompileError!Air.Inst.Ref { |
| 19820 | assert(unresolved_struct_ty.zigTypeTag() == .Struct); | 19827 | assert(unresolved_struct_ty.zigTypeTag() == .Struct); |
| 19821 | | 19828 | |
| ... | @@ -19828,10 +19835,10 @@ fn structFieldPtr( | ... | @@ -19828,10 +19835,10 @@ fn structFieldPtr( |
| 19828 | return sema.analyzeRef(block, src, len_inst); | 19835 | return sema.analyzeRef(block, src, len_inst); |
| 19829 | } | 19836 | } |
| 19830 | const field_index = try sema.tupleFieldIndex(block, struct_ty, field_name, field_name_src); | 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 | } else if (struct_ty.isAnonStruct()) { | 19839 | } else if (struct_ty.isAnonStruct()) { |
| 19833 | const field_index = try sema.anonStructFieldIndex(block, struct_ty, field_name, field_name_src); | 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 | const struct_obj = struct_ty.castTag(.@"struct").?.data; | 19844 | const struct_obj = struct_ty.castTag(.@"struct").?.data; |
| ... | @@ -19840,7 +19847,7 @@ fn structFieldPtr( | ... | @@ -19840,7 +19847,7 @@ fn structFieldPtr( |
| 19840 | return sema.failWithBadStructFieldAccess(block, struct_obj, field_name_src, field_name); | 19847 | return sema.failWithBadStructFieldAccess(block, struct_obj, field_name_src, field_name); |
| 19841 | const field_index = @intCast(u32, field_index_big); | 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 | fn structFieldPtrByIndex( | 19853 | fn structFieldPtrByIndex( |
| ... | @@ -19851,9 +19858,10 @@ fn structFieldPtrByIndex( | ... | @@ -19851,9 +19858,10 @@ fn structFieldPtrByIndex( |
| 19851 | field_index: u32, | 19858 | field_index: u32, |
| 19852 | field_src: LazySrcLoc, | 19859 | field_src: LazySrcLoc, |
| 19853 | struct_ty: Type, | 19860 | struct_ty: Type, |
| | 19861 | initializing: bool, |
| 19854 | ) CompileError!Air.Inst.Ref { | 19862 | ) CompileError!Air.Inst.Ref { |
| 19855 | if (struct_ty.isAnonStruct()) { | 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 | const struct_obj = struct_ty.castTag(.@"struct").?.data; | 19867 | const struct_obj = struct_ty.castTag(.@"struct").?.data; |
| ... | @@ -20050,6 +20058,10 @@ fn tupleFieldValByIndex( | ... | @@ -20050,6 +20058,10 @@ fn tupleFieldValByIndex( |
| 20050 | return sema.addConstant(field_ty, field_values[field_index]); | 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 | try sema.requireRuntimeBlock(block, src, null); | 20065 | try sema.requireRuntimeBlock(block, src, null); |
| 20054 | return block.addStructFieldVal(tuple_byval, field_index, field_ty); | 20066 | return block.addStructFieldVal(tuple_byval, field_index, field_ty); |
| 20055 | } | 20067 | } |
| ... | @@ -20250,7 +20262,7 @@ fn elemPtr( | ... | @@ -20250,7 +20262,7 @@ fn elemPtr( |
| 20250 | // Tuple field access. | 20262 | // Tuple field access. |
| 20251 | const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index, "tuple field access index must be comptime known"); | 20263 | const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index, "tuple field access index must be comptime known"); |
| 20252 | const index = @intCast(u32, index_val.toUnsignedInt(target)); | 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 | else => unreachable, | 20267 | else => unreachable, |
| 20256 | } | 20268 | } |
| ... | @@ -20353,6 +20365,7 @@ fn tupleFieldPtr( | ... | @@ -20353,6 +20365,7 @@ fn tupleFieldPtr( |
| 20353 | tuple_ptr: Air.Inst.Ref, | 20365 | tuple_ptr: Air.Inst.Ref, |
| 20354 | field_index_src: LazySrcLoc, | 20366 | field_index_src: LazySrcLoc, |
| 20355 | field_index: u32, | 20367 | field_index: u32, |
| | 20368 | init: bool, |
| 20356 | ) CompileError!Air.Inst.Ref { | 20369 | ) CompileError!Air.Inst.Ref { |
| 20357 | const tuple_ptr_ty = sema.typeOf(tuple_ptr); | 20370 | const tuple_ptr_ty = sema.typeOf(tuple_ptr); |
| 20358 | const tuple_ty = tuple_ptr_ty.childType(); | 20371 | const tuple_ty = tuple_ptr_ty.childType(); |
| ... | @@ -20386,7 +20399,17 @@ fn tupleFieldPtr( | ... | @@ -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 | try sema.requireRuntimeBlock(block, tuple_ptr_src, null); | 20414 | try sema.requireRuntimeBlock(block, tuple_ptr_src, null); |
| 20392 | return block.addStructFieldPtr(tuple_ptr, field_index, ptr_field_ty); | 20415 | return block.addStructFieldPtr(tuple_ptr, field_index, ptr_field_ty); |