| ... | @@ -3326,7 +3326,7 @@ fn zirValidateStructInit( | ... | @@ -3326,7 +3326,7 @@ fn zirValidateStructInit( |
| 3326 | switch (agg_ty.zigTypeTag()) { | 3326 | switch (agg_ty.zigTypeTag()) { |
| 3327 | .Struct => return sema.validateStructInit( | 3327 | .Struct => return sema.validateStructInit( |
| 3328 | block, | 3328 | block, |
| 3329 | agg_ty.castTag(.@"struct").?.data, | 3329 | agg_ty, |
| 3330 | init_src, | 3330 | init_src, |
| 3331 | instrs, | 3331 | instrs, |
| 3332 | is_comptime, | 3332 | is_comptime, |
| ... | @@ -3470,7 +3470,7 @@ fn validateUnionInit( | ... | @@ -3470,7 +3470,7 @@ fn validateUnionInit( |
| 3470 | fn validateStructInit( | 3470 | fn validateStructInit( |
| 3471 | sema: *Sema, | 3471 | sema: *Sema, |
| 3472 | block: *Block, | 3472 | block: *Block, |
| 3473 | struct_obj: *Module.Struct, | 3473 | struct_ty: Type, |
| 3474 | init_src: LazySrcLoc, | 3474 | init_src: LazySrcLoc, |
| 3475 | instrs: []const Zir.Inst.Index, | 3475 | instrs: []const Zir.Inst.Index, |
| 3476 | is_comptime: bool, | 3476 | is_comptime: bool, |
| ... | @@ -3478,7 +3478,7 @@ fn validateStructInit( | ... | @@ -3478,7 +3478,7 @@ fn validateStructInit( |
| 3478 | const gpa = sema.gpa; | 3478 | const gpa = sema.gpa; |
| 3479 | | 3479 | |
| 3480 | // Maps field index to field_ptr index of where it was already initialized. | 3480 | // Maps field index to field_ptr index of where it was already initialized. |
| 3481 | const found_fields = try gpa.alloc(Zir.Inst.Index, struct_obj.fields.count()); | 3481 | const found_fields = try gpa.alloc(Zir.Inst.Index, struct_ty.structFieldCount()); |
| 3482 | defer gpa.free(found_fields); | 3482 | defer gpa.free(found_fields); |
| 3483 | mem.set(Zir.Inst.Index, found_fields, 0); | 3483 | mem.set(Zir.Inst.Index, found_fields, 0); |
| 3484 | | 3484 | |
| ... | @@ -3490,8 +3490,7 @@ fn validateStructInit( | ... | @@ -3490,8 +3490,7 @@ fn validateStructInit( |
| 3490 | const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data; | 3490 | const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data; |
| 3491 | struct_ptr_zir_ref = field_ptr_extra.lhs; | 3491 | struct_ptr_zir_ref = field_ptr_extra.lhs; |
| 3492 | const field_name = sema.code.nullTerminatedString(field_ptr_extra.field_name_start); | 3492 | const field_name = sema.code.nullTerminatedString(field_ptr_extra.field_name_start); |
| 3493 | const field_index = struct_obj.fields.getIndex(field_name) orelse | 3493 | const field_index = try sema.structFieldIndex(block, struct_ty, field_name, field_src); |
| 3494 | return sema.failWithBadStructFieldAccess(block, struct_obj, field_src, field_name); | | |
| 3495 | if (found_fields[field_index] != 0) { | 3494 | if (found_fields[field_index] != 0) { |
| 3496 | const other_field_ptr = found_fields[field_index]; | 3495 | const other_field_ptr = found_fields[field_index]; |
| 3497 | const other_field_ptr_data = sema.code.instructions.items(.data)[other_field_ptr].pl_node; | 3496 | const other_field_ptr_data = sema.code.instructions.items(.data)[other_field_ptr].pl_node; |
| ... | @@ -3509,10 +3508,7 @@ fn validateStructInit( | ... | @@ -3509,10 +3508,7 @@ fn validateStructInit( |
| 3509 | | 3508 | |
| 3510 | var root_msg: ?*Module.ErrorMsg = null; | 3509 | var root_msg: ?*Module.ErrorMsg = null; |
| 3511 | | 3510 | |
| 3512 | const fields = struct_obj.fields.values(); | | |
| 3513 | const struct_ptr = try sema.resolveInst(struct_ptr_zir_ref); | 3511 | const struct_ptr = try sema.resolveInst(struct_ptr_zir_ref); |
| 3514 | const struct_ty = sema.typeOf(struct_ptr).childType(); | | |
| 3515 | | | |
| 3516 | if ((is_comptime or block.is_comptime) and | 3512 | if ((is_comptime or block.is_comptime) and |
| 3517 | (try sema.resolveDefinedValue(block, init_src, struct_ptr)) != null) | 3513 | (try sema.resolveDefinedValue(block, init_src, struct_ptr)) != null) |
| 3518 | { | 3514 | { |
| ... | @@ -3522,10 +3518,9 @@ fn validateStructInit( | ... | @@ -3522,10 +3518,9 @@ fn validateStructInit( |
| 3522 | for (found_fields) |field_ptr, i| { | 3518 | for (found_fields) |field_ptr, i| { |
| 3523 | if (field_ptr != 0) continue; | 3519 | if (field_ptr != 0) continue; |
| 3524 | | 3520 | |
| 3525 | const field = fields[i]; | 3521 | const default_val = struct_ty.structFieldDefaultValue(i); |
| 3526 | const field_name = struct_obj.fields.keys()[i]; | 3522 | if (default_val.tag() == .unreachable_value) { |
| 3527 | | 3523 | const field_name = struct_ty.structFieldName(i); |
| 3528 | if (field.default_val.tag() == .unreachable_value) { | | |
| 3529 | const template = "missing struct field: {s}"; | 3524 | const template = "missing struct field: {s}"; |
| 3530 | const args = .{field_name}; | 3525 | const args = .{field_name}; |
| 3531 | if (root_msg) |msg| { | 3526 | if (root_msg) |msg| { |
| ... | @@ -3536,22 +3531,25 @@ fn validateStructInit( | ... | @@ -3536,22 +3531,25 @@ fn validateStructInit( |
| 3536 | continue; | 3531 | continue; |
| 3537 | } | 3532 | } |
| 3538 | | 3533 | |
| 3539 | const default_field_ptr = try sema.structFieldPtr(block, init_src, struct_ptr, field_name, init_src, struct_ty); | | |
| 3540 | const init = try sema.addConstant(field.ty, field.default_val); | | |
| 3541 | const field_src = init_src; // TODO better source location | 3534 | const field_src = init_src; // TODO better source location |
| | 3535 | const default_field_ptr = try sema.structFieldPtrByIndex(block, init_src, struct_ptr, @intCast(u32, i), field_src, struct_ty); |
| | 3536 | const field_ty = sema.typeOf(default_field_ptr).childType(); |
| | 3537 | const init = try sema.addConstant(field_ty, default_val); |
| 3542 | try sema.storePtr2(block, init_src, default_field_ptr, init_src, init, field_src, .store); | 3538 | try sema.storePtr2(block, init_src, default_field_ptr, init_src, init, field_src, .store); |
| 3543 | } | 3539 | } |
| 3544 | | 3540 | |
| 3545 | if (root_msg) |msg| { | 3541 | if (root_msg) |msg| { |
| 3546 | const mod = sema.mod; | 3542 | if (struct_ty.castTag(.@"struct")) |struct_obj| { |
| 3547 | const fqn = try struct_obj.getFullyQualifiedName(mod); | 3543 | const mod = sema.mod; |
| 3548 | defer gpa.free(fqn); | 3544 | const fqn = try struct_obj.data.getFullyQualifiedName(mod); |
| 3549 | try mod.errNoteNonLazy( | 3545 | defer gpa.free(fqn); |
| 3550 | struct_obj.srcLoc(mod), | 3546 | try mod.errNoteNonLazy( |
| 3551 | msg, | 3547 | struct_obj.data.srcLoc(mod), |
| 3552 | "struct '{s}' declared here", | 3548 | msg, |
| 3553 | .{fqn}, | 3549 | "struct '{s}' declared here", |
| 3554 | ); | 3550 | .{fqn}, |
| | 3551 | ); |
| | 3552 | } |
| 3555 | return sema.failWithOwnedErrorMsg(block, msg); | 3553 | return sema.failWithOwnedErrorMsg(block, msg); |
| 3556 | } | 3554 | } |
| 3557 | | 3555 | |
| ... | @@ -3566,17 +3564,16 @@ fn validateStructInit( | ... | @@ -3566,17 +3564,16 @@ fn validateStructInit( |
| 3566 | | 3564 | |
| 3567 | // We collect the comptime field values in case the struct initialization | 3565 | // We collect the comptime field values in case the struct initialization |
| 3568 | // ends up being comptime-known. | 3566 | // ends up being comptime-known. |
| 3569 | const field_values = try sema.arena.alloc(Value, fields.len); | 3567 | const field_values = try sema.arena.alloc(Value, struct_ty.structFieldCount()); |
| 3570 | | 3568 | |
| 3571 | field: for (found_fields) |field_ptr, i| { | 3569 | field: for (found_fields) |field_ptr, i| { |
| 3572 | const field = fields[i]; | | |
| 3573 | | | |
| 3574 | if (field_ptr != 0) { | 3570 | if (field_ptr != 0) { |
| 3575 | const field_ptr_data = sema.code.instructions.items(.data)[field_ptr].pl_node; | 3571 | const field_ptr_data = sema.code.instructions.items(.data)[field_ptr].pl_node; |
| 3576 | const field_src: LazySrcLoc = .{ .node_offset_back2tok = field_ptr_data.src_node }; | 3572 | const field_src: LazySrcLoc = .{ .node_offset_back2tok = field_ptr_data.src_node }; |
| 3577 | | 3573 | |
| 3578 | // Determine whether the value stored to this pointer is comptime-known. | 3574 | // Determine whether the value stored to this pointer is comptime-known. |
| 3579 | if (try sema.typeHasOnePossibleValue(block, field_src, field.ty)) |opv| { | 3575 | const field_ty = struct_ty.structFieldType(i); |
| | 3576 | if (try sema.typeHasOnePossibleValue(block, field_src, field_ty)) |opv| { |
| 3580 | field_values[i] = opv; | 3577 | field_values[i] = opv; |
| 3581 | continue; | 3578 | continue; |
| 3582 | } | 3579 | } |
| ... | @@ -3648,9 +3645,9 @@ fn validateStructInit( | ... | @@ -3648,9 +3645,9 @@ fn validateStructInit( |
| 3648 | continue :field; | 3645 | continue :field; |
| 3649 | } | 3646 | } |
| 3650 | | 3647 | |
| 3651 | const field_name = struct_obj.fields.keys()[i]; | 3648 | const default_val = struct_ty.structFieldDefaultValue(i); |
| 3652 | | 3649 | if (default_val.tag() == .unreachable_value) { |
| 3653 | if (field.default_val.tag() == .unreachable_value) { | 3650 | const field_name = struct_ty.structFieldName(i); |
| 3654 | const template = "missing struct field: {s}"; | 3651 | const template = "missing struct field: {s}"; |
| 3655 | const args = .{field_name}; | 3652 | const args = .{field_name}; |
| 3656 | if (root_msg) |msg| { | 3653 | if (root_msg) |msg| { |
| ... | @@ -3660,17 +3657,20 @@ fn validateStructInit( | ... | @@ -3660,17 +3657,20 @@ fn validateStructInit( |
| 3660 | } | 3657 | } |
| 3661 | continue; | 3658 | continue; |
| 3662 | } | 3659 | } |
| | 3660 | field_values[i] = default_val; |
| 3663 | } | 3661 | } |
| 3664 | | 3662 | |
| 3665 | if (root_msg) |msg| { | 3663 | if (root_msg) |msg| { |
| 3666 | const fqn = try struct_obj.getFullyQualifiedName(sema.mod); | 3664 | if (struct_ty.castTag(.@"struct")) |struct_obj| { |
| 3667 | defer gpa.free(fqn); | 3665 | const fqn = try struct_obj.data.getFullyQualifiedName(sema.mod); |
| 3668 | try sema.mod.errNoteNonLazy( | 3666 | defer gpa.free(fqn); |
| 3669 | struct_obj.srcLoc(sema.mod), | 3667 | try sema.mod.errNoteNonLazy( |
| 3670 | msg, | 3668 | struct_obj.data.srcLoc(sema.mod), |
| 3671 | "struct '{s}' declared here", | 3669 | msg, |
| 3672 | .{fqn}, | 3670 | "struct '{s}' declared here", |
| 3673 | ); | 3671 | .{fqn}, |
| | 3672 | ); |
| | 3673 | } |
| 3674 | return sema.failWithOwnedErrorMsg(block, msg); | 3674 | return sema.failWithOwnedErrorMsg(block, msg); |
| 3675 | } | 3675 | } |
| 3676 | | 3676 | |
| ... | @@ -3679,15 +3679,6 @@ fn validateStructInit( | ... | @@ -3679,15 +3679,6 @@ fn validateStructInit( |
| 3679 | // instead a single `store` to the struct_ptr with a comptime struct value. | 3679 | // instead a single `store` to the struct_ptr with a comptime struct value. |
| 3680 | | 3680 | |
| 3681 | block.instructions.shrinkRetainingCapacity(first_block_index); | 3681 | block.instructions.shrinkRetainingCapacity(first_block_index); |
| 3682 | | | |
| 3683 | // The `field_values` array has been populated for all the non-default struct | | |
| 3684 | // fields. Here we fill in the default field values. | | |
| 3685 | for (found_fields) |field_ptr, i| { | | |
| 3686 | if (field_ptr != 0) continue; | | |
| 3687 | | | |
| 3688 | field_values[i] = fields[i].default_val; | | |
| 3689 | } | | |
| 3690 | | | |
| 3691 | const struct_val = try Value.Tag.aggregate.create(sema.arena, field_values); | 3682 | const struct_val = try Value.Tag.aggregate.create(sema.arena, field_values); |
| 3692 | const struct_init = try sema.addConstant(struct_ty, struct_val); | 3683 | const struct_init = try sema.addConstant(struct_ty, struct_val); |
| 3693 | try sema.storePtr2(block, init_src, struct_ptr, init_src, struct_init, init_src, .store); | 3684 | try sema.storePtr2(block, init_src, struct_ptr, init_src, struct_init, init_src, .store); |
| ... | @@ -3695,16 +3686,13 @@ fn validateStructInit( | ... | @@ -3695,16 +3686,13 @@ fn validateStructInit( |
| 3695 | } | 3686 | } |
| 3696 | | 3687 | |
| 3697 | // Our task is to insert `store` instructions for all the default field values. | 3688 | // Our task is to insert `store` instructions for all the default field values. |
| 3698 | | | |
| 3699 | for (found_fields) |field_ptr, i| { | 3689 | for (found_fields) |field_ptr, i| { |
| 3700 | if (field_ptr != 0) continue; | 3690 | if (field_ptr != 0) continue; |
| 3701 | | 3691 | |
| 3702 | const field = fields[i]; | | |
| 3703 | const field_name = struct_obj.fields.keys()[i]; | | |
| 3704 | const default_field_ptr = try sema.structFieldPtr(block, init_src, struct_ptr, field_name, init_src, struct_ty); | | |
| 3705 | | | |
| 3706 | const init = try sema.addConstant(field.ty, field.default_val); | | |
| 3707 | const field_src = init_src; // TODO better source location | 3692 | const field_src = init_src; // TODO better source location |
| | 3693 | const default_field_ptr = try sema.structFieldPtrByIndex(block, init_src, struct_ptr, @intCast(u32, i), field_src, struct_ty); |
| | 3694 | const field_ty = sema.typeOf(default_field_ptr).childType(); |
| | 3695 | const init = try sema.addConstant(field_ty, field_values[i]); |
| 3708 | try sema.storePtr2(block, init_src, default_field_ptr, init_src, init, field_src, .store); | 3696 | try sema.storePtr2(block, init_src, default_field_ptr, init_src, init, field_src, .store); |
| 3709 | } | 3697 | } |
| 3710 | } | 3698 | } |
| ... | @@ -13827,7 +13815,7 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE | ... | @@ -13827,7 +13815,7 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 13827 | const obj_ty = try sema.resolveType(block, src, inst_data.operand); | 13815 | const obj_ty = try sema.resolveType(block, src, inst_data.operand); |
| 13828 | | 13816 | |
| 13829 | switch (obj_ty.zigTypeTag()) { | 13817 | switch (obj_ty.zigTypeTag()) { |
| 13830 | .Struct => return structInitEmpty(sema, block, obj_ty, src, src), | 13818 | .Struct => return sema.structInitEmpty(block, obj_ty, src, src), |
| 13831 | .Array => return arrayInitEmpty(sema, obj_ty), | 13819 | .Array => return arrayInitEmpty(sema, obj_ty), |
| 13832 | .Void => return sema.addConstant(obj_ty, Value.void), | 13820 | .Void => return sema.addConstant(obj_ty, Value.void), |
| 13833 | else => return sema.failWithArrayInitNotSupported(block, src, obj_ty), | 13821 | else => return sema.failWithArrayInitNotSupported(block, src, obj_ty), |
| ... | @@ -13844,29 +13832,13 @@ fn structInitEmpty( | ... | @@ -13844,29 +13832,13 @@ fn structInitEmpty( |
| 13844 | const gpa = sema.gpa; | 13832 | const gpa = sema.gpa; |
| 13845 | // This logic must be synchronized with that in `zirStructInit`. | 13833 | // This logic must be synchronized with that in `zirStructInit`. |
| 13846 | const struct_ty = try sema.resolveTypeFields(block, dest_src, obj_ty); | 13834 | const struct_ty = try sema.resolveTypeFields(block, dest_src, obj_ty); |
| 13847 | const struct_obj = struct_ty.castTag(.@"struct").?.data; | | |
| 13848 | | 13835 | |
| 13849 | // The init values to use for the struct instance. | 13836 | // The init values to use for the struct instance. |
| 13850 | const field_inits = try gpa.alloc(Air.Inst.Ref, struct_obj.fields.count()); | 13837 | const field_inits = try gpa.alloc(Air.Inst.Ref, struct_ty.structFieldCount()); |
| 13851 | defer gpa.free(field_inits); | 13838 | defer gpa.free(field_inits); |
| | 13839 | mem.set(Air.Inst.Ref, field_inits, .none); |
| 13852 | | 13840 | |
| 13853 | var root_msg: ?*Module.ErrorMsg = null; | 13841 | return sema.finishStructInit(block, init_src, dest_src, field_inits, struct_ty, false); |
| 13854 | | | |
| 13855 | for (struct_obj.fields.values()) |field, i| { | | |
| 13856 | if (field.default_val.tag() == .unreachable_value) { | | |
| 13857 | const field_name = struct_obj.fields.keys()[i]; | | |
| 13858 | const template = "missing struct field: {s}"; | | |
| 13859 | const args = .{field_name}; | | |
| 13860 | if (root_msg) |msg| { | | |
| 13861 | try sema.errNote(block, init_src, msg, template, args); | | |
| 13862 | } else { | | |
| 13863 | root_msg = try sema.errMsg(block, init_src, template, args); | | |
| 13864 | } | | |
| 13865 | } else { | | |
| 13866 | field_inits[i] = try sema.addConstant(field.ty, field.default_val); | | |
| 13867 | } | | |
| 13868 | } | | |
| 13869 | return sema.finishStructInit(block, dest_src, field_inits, root_msg, struct_obj, struct_ty, false); | | |
| 13870 | } | 13842 | } |
| 13871 | | 13843 | |
| 13872 | fn arrayInitEmpty(sema: *Sema, obj_ty: Type) CompileError!Air.Inst.Ref { | 13844 | fn arrayInitEmpty(sema: *Sema, obj_ty: Type) CompileError!Air.Inst.Ref { |
| ... | @@ -13936,19 +13908,18 @@ fn zirStructInit( | ... | @@ -13936,19 +13908,18 @@ fn zirStructInit( |
| 13936 | const unresolved_struct_type = try sema.resolveType(block, src, first_field_type_extra.container_type); | 13908 | const unresolved_struct_type = try sema.resolveType(block, src, first_field_type_extra.container_type); |
| 13937 | const resolved_ty = try sema.resolveTypeFields(block, src, unresolved_struct_type); | 13909 | const resolved_ty = try sema.resolveTypeFields(block, src, unresolved_struct_type); |
| 13938 | | 13910 | |
| 13939 | if (resolved_ty.castTag(.@"struct")) |struct_payload| { | 13911 | if (resolved_ty.zigTypeTag() == .Struct) { |
| 13940 | // This logic must be synchronized with that in `zirStructInitEmpty`. | 13912 | // This logic must be synchronized with that in `zirStructInitEmpty`. |
| 13941 | const struct_obj = struct_payload.data; | | |
| 13942 | | 13913 | |
| 13943 | // Maps field index to field_type index of where it was already initialized. | 13914 | // Maps field index to field_type index of where it was already initialized. |
| 13944 | // For making sure all fields are accounted for and no fields are duplicated. | 13915 | // For making sure all fields are accounted for and no fields are duplicated. |
| 13945 | const found_fields = try gpa.alloc(Zir.Inst.Index, struct_obj.fields.count()); | 13916 | const found_fields = try gpa.alloc(Zir.Inst.Index, resolved_ty.structFieldCount()); |
| 13946 | defer gpa.free(found_fields); | 13917 | defer gpa.free(found_fields); |
| 13947 | mem.set(Zir.Inst.Index, found_fields, 0); | | |
| 13948 | | 13918 | |
| 13949 | // The init values to use for the struct instance. | 13919 | // The init values to use for the struct instance. |
| 13950 | const field_inits = try gpa.alloc(Air.Inst.Ref, struct_obj.fields.count()); | 13920 | const field_inits = try gpa.alloc(Air.Inst.Ref, resolved_ty.structFieldCount()); |
| 13951 | defer gpa.free(field_inits); | 13921 | defer gpa.free(field_inits); |
| | 13922 | mem.set(Air.Inst.Ref, field_inits, .none); |
| 13952 | | 13923 | |
| 13953 | var field_i: u32 = 0; | 13924 | var field_i: u32 = 0; |
| 13954 | var extra_index = extra.end; | 13925 | var extra_index = extra.end; |
| ... | @@ -13961,9 +13932,8 @@ fn zirStructInit( | ... | @@ -13961,9 +13932,8 @@ fn zirStructInit( |
| 13961 | const field_src: LazySrcLoc = .{ .node_offset_back2tok = field_type_data.src_node }; | 13932 | const field_src: LazySrcLoc = .{ .node_offset_back2tok = field_type_data.src_node }; |
| 13962 | const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data; | 13933 | const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data; |
| 13963 | const field_name = sema.code.nullTerminatedString(field_type_extra.name_start); | 13934 | const field_name = sema.code.nullTerminatedString(field_type_extra.name_start); |
| 13964 | const field_index = struct_obj.fields.getIndex(field_name) orelse | 13935 | const field_index = try sema.structFieldIndex(block, resolved_ty, field_name, field_src); |
| 13965 | return sema.failWithBadStructFieldAccess(block, struct_obj, field_src, field_name); | 13936 | if (field_inits[field_index] != .none) { |
| 13966 | if (found_fields[field_index] != 0) { | | |
| 13967 | const other_field_type = found_fields[field_index]; | 13937 | const other_field_type = found_fields[field_index]; |
| 13968 | const other_field_type_data = zir_datas[other_field_type].pl_node; | 13938 | const other_field_type_data = zir_datas[other_field_type].pl_node; |
| 13969 | const other_field_src: LazySrcLoc = .{ .node_offset_back2tok = other_field_type_data.src_node }; | 13939 | const other_field_src: LazySrcLoc = .{ .node_offset_back2tok = other_field_type_data.src_node }; |
| ... | @@ -13979,27 +13949,7 @@ fn zirStructInit( | ... | @@ -13979,27 +13949,7 @@ fn zirStructInit( |
| 13979 | field_inits[field_index] = try sema.resolveInst(item.data.init); | 13949 | field_inits[field_index] = try sema.resolveInst(item.data.init); |
| 13980 | } | 13950 | } |
| 13981 | | 13951 | |
| 13982 | var root_msg: ?*Module.ErrorMsg = null; | 13952 | return sema.finishStructInit(block, src, src, field_inits, resolved_ty, is_ref); |
| 13983 | | | |
| 13984 | for (found_fields) |field_type_inst, i| { | | |
| 13985 | if (field_type_inst != 0) continue; | | |
| 13986 | | | |
| 13987 | // Check if the field has a default init. | | |
| 13988 | const field = struct_obj.fields.values()[i]; | | |
| 13989 | if (field.default_val.tag() == .unreachable_value) { | | |
| 13990 | const field_name = struct_obj.fields.keys()[i]; | | |
| 13991 | const template = "missing struct field: {s}"; | | |
| 13992 | const args = .{field_name}; | | |
| 13993 | if (root_msg) |msg| { | | |
| 13994 | try sema.errNote(block, src, msg, template, args); | | |
| 13995 | } else { | | |
| 13996 | root_msg = try sema.errMsg(block, src, template, args); | | |
| 13997 | } | | |
| 13998 | } else { | | |
| 13999 | field_inits[i] = try sema.addConstant(field.ty, field.default_val); | | |
| 14000 | } | | |
| 14001 | } | | |
| 14002 | return sema.finishStructInit(block, src, field_inits, root_msg, struct_obj, resolved_ty, is_ref); | | |
| 14003 | } else if (resolved_ty.zigTypeTag() == .Union) { | 13953 | } else if (resolved_ty.zigTypeTag() == .Union) { |
| 14004 | if (extra.data.fields_len != 1) { | 13954 | if (extra.data.fields_len != 1) { |
| 14005 | return sema.fail(block, src, "union initialization expects exactly one field", .{}); | 13955 | return sema.fail(block, src, "union initialization expects exactly one field", .{}); |
| ... | @@ -14051,29 +14001,69 @@ fn zirStructInit( | ... | @@ -14051,29 +14001,69 @@ fn zirStructInit( |
| 14051 | fn finishStructInit( | 14001 | fn finishStructInit( |
| 14052 | sema: *Sema, | 14002 | sema: *Sema, |
| 14053 | block: *Block, | 14003 | block: *Block, |
| 14054 | src: LazySrcLoc, | 14004 | init_src: LazySrcLoc, |
| 14055 | field_inits: []const Air.Inst.Ref, | 14005 | dest_src: LazySrcLoc, |
| 14056 | root_msg: ?*Module.ErrorMsg, | 14006 | field_inits: []Air.Inst.Ref, |
| 14057 | struct_obj: *Module.Struct, | | |
| 14058 | struct_ty: Type, | 14007 | struct_ty: Type, |
| 14059 | is_ref: bool, | 14008 | is_ref: bool, |
| 14060 | ) !Air.Inst.Ref { | 14009 | ) CompileError!Air.Inst.Ref { |
| 14061 | const gpa = sema.gpa; | 14010 | const gpa = sema.gpa; |
| 14062 | | 14011 | |
| | 14012 | var root_msg: ?*Module.ErrorMsg = null; |
| | 14013 | if (struct_ty.isAnonStruct()) { |
| | 14014 | const struct_obj = struct_ty.castTag(.anon_struct).?.data; |
| | 14015 | for (struct_obj.values) |default_val, i| { |
| | 14016 | if (field_inits[i] != .none) continue; |
| | 14017 | |
| | 14018 | if (default_val.tag() == .unreachable_value) { |
| | 14019 | const field_name = struct_obj.names[i]; |
| | 14020 | const template = "missing struct field: {s}"; |
| | 14021 | const args = .{field_name}; |
| | 14022 | if (root_msg) |msg| { |
| | 14023 | try sema.errNote(block, init_src, msg, template, args); |
| | 14024 | } else { |
| | 14025 | root_msg = try sema.errMsg(block, init_src, template, args); |
| | 14026 | } |
| | 14027 | } else { |
| | 14028 | field_inits[i] = try sema.addConstant(struct_obj.types[i], default_val); |
| | 14029 | } |
| | 14030 | } |
| | 14031 | } else { |
| | 14032 | const struct_obj = struct_ty.castTag(.@"struct").?.data; |
| | 14033 | for (struct_obj.fields.values()) |field, i| { |
| | 14034 | if (field_inits[i] != .none) continue; |
| | 14035 | |
| | 14036 | if (field.default_val.tag() == .unreachable_value) { |
| | 14037 | const field_name = struct_obj.fields.keys()[i]; |
| | 14038 | const template = "missing struct field: {s}"; |
| | 14039 | const args = .{field_name}; |
| | 14040 | if (root_msg) |msg| { |
| | 14041 | try sema.errNote(block, init_src, msg, template, args); |
| | 14042 | } else { |
| | 14043 | root_msg = try sema.errMsg(block, init_src, template, args); |
| | 14044 | } |
| | 14045 | } else { |
| | 14046 | field_inits[i] = try sema.addConstant(field.ty, field.default_val); |
| | 14047 | } |
| | 14048 | } |
| | 14049 | } |
| | 14050 | |
| 14063 | if (root_msg) |msg| { | 14051 | if (root_msg) |msg| { |
| 14064 | const fqn = try struct_obj.getFullyQualifiedName(sema.mod); | 14052 | if (struct_ty.castTag(.@"struct")) |struct_obj| { |
| 14065 | defer gpa.free(fqn); | 14053 | const fqn = try struct_obj.data.getFullyQualifiedName(sema.mod); |
| 14066 | try sema.mod.errNoteNonLazy( | 14054 | defer gpa.free(fqn); |
| 14067 | struct_obj.srcLoc(sema.mod), | 14055 | try sema.mod.errNoteNonLazy( |
| 14068 | msg, | 14056 | struct_obj.data.srcLoc(sema.mod), |
| 14069 | "struct '{s}' declared here", | 14057 | msg, |
| 14070 | .{fqn}, | 14058 | "struct '{s}' declared here", |
| 14071 | ); | 14059 | .{fqn}, |
| | 14060 | ); |
| | 14061 | } |
| 14072 | return sema.failWithOwnedErrorMsg(block, msg); | 14062 | return sema.failWithOwnedErrorMsg(block, msg); |
| 14073 | } | 14063 | } |
| 14074 | | 14064 | |
| 14075 | const is_comptime = for (field_inits) |field_init| { | 14065 | const is_comptime = for (field_inits) |field_init| { |
| 14076 | if (!(try sema.isComptimeKnown(block, src, field_init))) { | 14066 | if (!(try sema.isComptimeKnown(block, dest_src, field_init))) { |
| 14077 | break false; | 14067 | break false; |
| 14078 | } | 14068 | } |
| 14079 | } else true; | 14069 | } else true; |
| ... | @@ -14081,10 +14071,10 @@ fn finishStructInit( | ... | @@ -14081,10 +14071,10 @@ fn finishStructInit( |
| 14081 | if (is_comptime) { | 14071 | if (is_comptime) { |
| 14082 | const values = try sema.arena.alloc(Value, field_inits.len); | 14072 | const values = try sema.arena.alloc(Value, field_inits.len); |
| 14083 | for (field_inits) |field_init, i| { | 14073 | for (field_inits) |field_init, i| { |
| 14084 | values[i] = (sema.resolveMaybeUndefVal(block, src, field_init) catch unreachable).?; | 14074 | values[i] = (sema.resolveMaybeUndefVal(block, dest_src, field_init) catch unreachable).?; |
| 14085 | } | 14075 | } |
| 14086 | const struct_val = try Value.Tag.aggregate.create(sema.arena, values); | 14076 | const struct_val = try Value.Tag.aggregate.create(sema.arena, values); |
| 14087 | return sema.addConstantMaybeRef(block, src, struct_ty, struct_val, is_ref); | 14077 | return sema.addConstantMaybeRef(block, dest_src, struct_ty, struct_val, is_ref); |
| 14088 | } | 14078 | } |
| 14089 | | 14079 | |
| 14090 | if (is_ref) { | 14080 | if (is_ref) { |
| ... | @@ -14096,15 +14086,15 @@ fn finishStructInit( | ... | @@ -14096,15 +14086,15 @@ fn finishStructInit( |
| 14096 | const alloc = try block.addTy(.alloc, alloc_ty); | 14086 | const alloc = try block.addTy(.alloc, alloc_ty); |
| 14097 | for (field_inits) |field_init, i_usize| { | 14087 | for (field_inits) |field_init, i_usize| { |
| 14098 | const i = @intCast(u32, i_usize); | 14088 | const i = @intCast(u32, i_usize); |
| 14099 | const field_src = src; | 14089 | const field_src = dest_src; |
| 14100 | const field_ptr = try sema.structFieldPtrByIndex(block, src, alloc, i, struct_obj, field_src); | 14090 | const field_ptr = try sema.structFieldPtrByIndex(block, dest_src, alloc, i, field_src, struct_ty); |
| 14101 | try sema.storePtr(block, src, field_ptr, field_init); | 14091 | try sema.storePtr(block, dest_src, field_ptr, field_init); |
| 14102 | } | 14092 | } |
| 14103 | | 14093 | |
| 14104 | return alloc; | 14094 | return alloc; |
| 14105 | } | 14095 | } |
| 14106 | | 14096 | |
| 14107 | try sema.requireRuntimeBlock(block, src); | 14097 | try sema.requireRuntimeBlock(block, dest_src); |
| 14108 | try sema.queueFullTypeResolution(struct_ty); | 14098 | try sema.queueFullTypeResolution(struct_ty); |
| 14109 | return block.addAggregateInit(struct_ty, field_inits); | 14099 | return block.addAggregateInit(struct_ty, field_inits); |
| 14110 | } | 14100 | } |
| ... | @@ -15872,7 +15862,8 @@ fn zirOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -15872,7 +15862,8 @@ fn zirOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15872 | | 15862 | |
| 15873 | fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u64 { | 15863 | fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u64 { |
| 15874 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 15864 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 15875 | sema.src = .{ .node_offset_bin_op = inst_data.src_node }; | 15865 | const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node }; |
| | 15866 | sema.src = src; |
| 15876 | const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; | 15867 | const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; |
| 15877 | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; | 15868 | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; |
| 15878 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 15869 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| ... | @@ -15882,50 +15873,38 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6 | ... | @@ -15882,50 +15873,38 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6 |
| 15882 | const target = sema.mod.getTarget(); | 15873 | const target = sema.mod.getTarget(); |
| 15883 | | 15874 | |
| 15884 | try sema.resolveTypeLayout(block, lhs_src, ty); | 15875 | try sema.resolveTypeLayout(block, lhs_src, ty); |
| 15885 | if (ty.tag() != .@"struct") { | 15876 | switch (ty.tag()) { |
| 15886 | const msg = msg: { | 15877 | .@"struct", .tuple, .anon_struct => {}, |
| 15887 | const msg = try sema.errMsg(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(sema.mod)}); | 15878 | else => { |
| 15888 | errdefer msg.destroy(sema.gpa); | 15879 | const msg = msg: { |
| 15889 | try sema.addDeclaredHereNote(msg, ty); | 15880 | const msg = try sema.errMsg(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(sema.mod)}); |
| 15890 | break :msg msg; | 15881 | errdefer msg.destroy(sema.gpa); |
| 15891 | }; | 15882 | try sema.addDeclaredHereNote(msg, ty); |
| 15892 | return sema.failWithOwnedErrorMsg(block, msg); | 15883 | break :msg msg; |
| | 15884 | }; |
| | 15885 | return sema.failWithOwnedErrorMsg(block, msg); |
| | 15886 | }, |
| 15893 | } | 15887 | } |
| 15894 | | 15888 | |
| 15895 | const fields = ty.structFields(); | 15889 | const field_index = if (ty.isTuple()) blk: { |
| 15896 | const index = fields.getIndex(field_name) orelse { | 15890 | if (mem.eql(u8, field_name, "len")) { |
| 15897 | const msg = msg: { | 15891 | return sema.fail(block, src, "no offset available for 'len' field of tuple", .{}); |
| 15898 | const msg = try sema.errMsg( | 15892 | } |
| 15899 | block, | 15893 | break :blk try sema.tupleFieldIndex(block, ty, field_name, rhs_src); |
| 15900 | rhs_src, | 15894 | } else try sema.structFieldIndex(block, ty, field_name, rhs_src); |
| 15901 | "struct '{}' has no field '{s}'", | | |
| 15902 | .{ ty.fmt(sema.mod), field_name }, | | |
| 15903 | ); | | |
| 15904 | errdefer msg.destroy(sema.gpa); | | |
| 15905 | try sema.addDeclaredHereNote(msg, ty); | | |
| 15906 | break :msg msg; | | |
| 15907 | }; | | |
| 15908 | return sema.failWithOwnedErrorMsg(block, msg); | | |
| 15909 | }; | | |
| 15910 | | 15895 | |
| 15911 | switch (ty.containerLayout()) { | 15896 | switch (ty.containerLayout()) { |
| 15912 | .Packed => { | 15897 | .Packed => { |
| 15913 | var bit_sum: u64 = 0; | 15898 | var bit_sum: u64 = 0; |
| | 15899 | const fields = ty.structFields(); |
| 15914 | for (fields.values()) |field, i| { | 15900 | for (fields.values()) |field, i| { |
| 15915 | if (i == index) { | 15901 | if (i == field_index) { |
| 15916 | return bit_sum; | 15902 | return bit_sum; |
| 15917 | } | 15903 | } |
| 15918 | bit_sum += field.ty.bitSize(target); | 15904 | bit_sum += field.ty.bitSize(target); |
| 15919 | } else unreachable; | 15905 | } else unreachable; |
| 15920 | }, | 15906 | }, |
| 15921 | else => { | 15907 | else => return ty.structFieldOffset(field_index, target) * 8, |
| 15922 | var it = ty.iterateStructOffsets(target); | | |
| 15923 | while (it.next()) |field_offset| { | | |
| 15924 | if (field_offset.field == index) { | | |
| 15925 | return field_offset.offset * 8; | | |
| 15926 | } | | |
| 15927 | } else unreachable; | | |
| 15928 | }, | | |
| 15929 | } | 15908 | } |
| 15930 | } | 15909 | } |
| 15931 | | 15910 | |
| ... | @@ -17193,24 +17172,28 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -17193,24 +17172,28 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 17193 | } | 17172 | } |
| 17194 | try sema.resolveTypeLayout(block, ty_src, struct_ty); | 17173 | try sema.resolveTypeLayout(block, ty_src, struct_ty); |
| 17195 | | 17174 | |
| 17196 | const struct_obj = struct_ty.castTag(.@"struct").?.data; | 17175 | const field_index = if (struct_ty.isTuple()) blk: { |
| 17197 | const field_index = struct_obj.fields.getIndex(field_name) orelse | 17176 | if (mem.eql(u8, field_name, "len")) { |
| 17198 | return sema.failWithBadStructFieldAccess(block, struct_obj, name_src, field_name); | 17177 | return sema.fail(block, src, "cannot get @fieldParentPtr of 'len' field of tuple", .{}); |
| | 17178 | } |
| | 17179 | break :blk try sema.tupleFieldIndex(block, struct_ty, field_name, name_src); |
| | 17180 | } else try sema.structFieldIndex(block, struct_ty, field_name, name_src); |
| 17199 | | 17181 | |
| 17200 | try sema.checkPtrOperand(block, ptr_src, field_ptr_ty); | 17182 | try sema.checkPtrOperand(block, ptr_src, field_ptr_ty); |
| 17201 | const field = struct_obj.fields.values()[field_index]; | | |
| 17202 | const field_ptr_ty_info = field_ptr_ty.ptrInfo().data; | 17183 | const field_ptr_ty_info = field_ptr_ty.ptrInfo().data; |
| 17203 | | 17184 | |
| 17204 | var ptr_ty_data: Type.Payload.Pointer.Data = .{ | 17185 | var ptr_ty_data: Type.Payload.Pointer.Data = .{ |
| 17205 | .pointee_type = field.ty, | 17186 | .pointee_type = struct_ty.structFieldType(field_index), |
| 17206 | .mutable = field_ptr_ty_info.mutable, | 17187 | .mutable = field_ptr_ty_info.mutable, |
| 17207 | .@"addrspace" = field_ptr_ty_info.@"addrspace", | 17188 | .@"addrspace" = field_ptr_ty_info.@"addrspace", |
| 17208 | }; | 17189 | }; |
| 17209 | | 17190 | |
| 17210 | if (struct_obj.layout == .Packed) { | 17191 | if (struct_ty.containerLayout() == .Packed) { |
| 17211 | return sema.fail(block, src, "TODO handle packed structs with @fieldParentPtr", .{}); | 17192 | return sema.fail(block, src, "TODO handle packed structs with @fieldParentPtr", .{}); |
| 17212 | } else { | 17193 | } else { |
| 17213 | ptr_ty_data.@"align" = field.abi_align; | 17194 | ptr_ty_data.@"align" = if (struct_ty.castTag(.@"struct")) |struct_obj| b: { |
| | 17195 | break :b struct_obj.data.fields.values()[field_index].abi_align; |
| | 17196 | } else 0; |
| 17214 | } | 17197 | } |
| 17215 | | 17198 | |
| 17216 | const actual_field_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_ty_data); | 17199 | const actual_field_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_ty_data); |
| ... | @@ -19059,7 +19042,7 @@ fn structFieldPtr( | ... | @@ -19059,7 +19042,7 @@ fn structFieldPtr( |
| 19059 | return sema.failWithBadStructFieldAccess(block, struct_obj, field_name_src, field_name); | 19042 | return sema.failWithBadStructFieldAccess(block, struct_obj, field_name_src, field_name); |
| 19060 | const field_index = @intCast(u32, field_index_big); | 19043 | const field_index = @intCast(u32, field_index_big); |
| 19061 | | 19044 | |
| 19062 | return sema.structFieldPtrByIndex(block, src, struct_ptr, field_index, struct_obj, field_name_src); | 19045 | return sema.structFieldPtrByIndex(block, src, struct_ptr, field_index, field_name_src, struct_ty); |
| 19063 | } | 19046 | } |
| 19064 | | 19047 | |
| 19065 | fn structFieldPtrByIndex( | 19048 | fn structFieldPtrByIndex( |
| ... | @@ -19068,9 +19051,14 @@ fn structFieldPtrByIndex( | ... | @@ -19068,9 +19051,14 @@ fn structFieldPtrByIndex( |
| 19068 | src: LazySrcLoc, | 19051 | src: LazySrcLoc, |
| 19069 | struct_ptr: Air.Inst.Ref, | 19052 | struct_ptr: Air.Inst.Ref, |
| 19070 | field_index: u32, | 19053 | field_index: u32, |
| 19071 | struct_obj: *Module.Struct, | | |
| 19072 | field_src: LazySrcLoc, | 19054 | field_src: LazySrcLoc, |
| | 19055 | struct_ty: Type, |
| 19073 | ) CompileError!Air.Inst.Ref { | 19056 | ) CompileError!Air.Inst.Ref { |
| | 19057 | if (struct_ty.isAnonStruct()) { |
| | 19058 | return sema.tupleFieldPtr(block, src, struct_ptr, field_src, field_index); |
| | 19059 | } |
| | 19060 | |
| | 19061 | const struct_obj = struct_ty.castTag(.@"struct").?.data; |
| 19074 | const field = struct_obj.fields.values()[field_index]; | 19062 | const field = struct_obj.fields.values()[field_index]; |
| 19075 | const struct_ptr_ty = sema.typeOf(struct_ptr); | 19063 | const struct_ptr_ty = sema.typeOf(struct_ptr); |
| 19076 | const struct_ptr_ty_info = struct_ptr_ty.ptrInfo().data; | 19064 | const struct_ptr_ty_info = struct_ptr_ty.ptrInfo().data; |
| ... | @@ -19231,17 +19219,13 @@ fn tupleFieldIndex( | ... | @@ -19231,17 +19219,13 @@ fn tupleFieldIndex( |
| 19231 | field_name: []const u8, | 19219 | field_name: []const u8, |
| 19232 | field_name_src: LazySrcLoc, | 19220 | field_name_src: LazySrcLoc, |
| 19233 | ) CompileError!u32 { | 19221 | ) CompileError!u32 { |
| 19234 | const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| { | 19222 | if (std.fmt.parseUnsigned(u32, field_name, 10)) |field_index| { |
| 19235 | return sema.fail(block, field_name_src, "tuple '{}' has no such field '{s}': {s}", .{ | 19223 | if (field_index < tuple_ty.structFieldCount()) return field_index; |
| 19236 | tuple_ty.fmt(sema.mod), field_name, @errorName(err), | 19224 | } else |_| {} |
| 19237 | }); | 19225 | |
| 19238 | }; | 19226 | return sema.fail(block, field_name_src, "no field named '{s}' in tuple '{}'", .{ |
| 19239 | if (field_index >= tuple_ty.structFieldCount()) { | 19227 | field_name, tuple_ty.fmt(sema.mod), |
| 19240 | return sema.fail(block, field_name_src, "tuple '{}' has no such field '{s}'", .{ | 19228 | }); |
| 19241 | tuple_ty.fmt(sema.mod), field_name, | | |
| 19242 | }); | | |
| 19243 | } | | |
| 19244 | return field_index; | | |
| 19245 | } | 19229 | } |
| 19246 | | 19230 | |
| 19247 | fn tupleFieldValByIndex( | 19231 | fn tupleFieldValByIndex( |
| ... | @@ -20356,7 +20340,7 @@ fn coerce( | ... | @@ -20356,7 +20340,7 @@ fn coerce( |
| 20356 | }, | 20340 | }, |
| 20357 | .Struct => { | 20341 | .Struct => { |
| 20358 | if (inst == .empty_struct) { | 20342 | if (inst == .empty_struct) { |
| 20359 | return structInitEmpty(sema, block, dest_ty, dest_ty_src, inst_src); | 20343 | return sema.structInitEmpty(block, dest_ty, dest_ty_src, inst_src); |
| 20360 | } | 20344 | } |
| 20361 | if (inst_ty.isTupleOrAnonStruct()) { | 20345 | if (inst_ty.isTupleOrAnonStruct()) { |
| 20362 | return sema.coerceTupleToStruct(block, dest_ty, dest_ty_src, inst, inst_src); | 20346 | return sema.coerceTupleToStruct(block, dest_ty, dest_ty_src, inst, inst_src); |
| ... | @@ -25754,10 +25738,14 @@ fn structFieldIndex( | ... | @@ -25754,10 +25738,14 @@ fn structFieldIndex( |
| 25754 | field_src: LazySrcLoc, | 25738 | field_src: LazySrcLoc, |
| 25755 | ) !u32 { | 25739 | ) !u32 { |
| 25756 | const struct_ty = try sema.resolveTypeFields(block, field_src, unresolved_struct_ty); | 25740 | const struct_ty = try sema.resolveTypeFields(block, field_src, unresolved_struct_ty); |
| 25757 | const struct_obj = struct_ty.castTag(.@"struct").?.data; | 25741 | if (struct_ty.isAnonStruct()) { |
| 25758 | const field_index_usize = struct_obj.fields.getIndex(field_name) orelse | 25742 | return sema.anonStructFieldIndex(block, struct_ty, field_name, field_src); |
| 25759 | return sema.failWithBadStructFieldAccess(block, struct_obj, field_src, field_name); | 25743 | } else { |
| 25760 | return @intCast(u32, field_index_usize); | 25744 | const struct_obj = struct_ty.castTag(.@"struct").?.data; |
| | 25745 | const field_index_usize = struct_obj.fields.getIndex(field_name) orelse |
| | 25746 | return sema.failWithBadStructFieldAccess(block, struct_obj, field_src, field_name); |
| | 25747 | return @intCast(u32, field_index_usize); |
| | 25748 | } |
| 25761 | } | 25749 | } |
| 25762 | | 25750 | |
| 25763 | fn anonStructFieldIndex( | 25751 | fn anonStructFieldIndex( |
| ... | @@ -25773,8 +25761,8 @@ fn anonStructFieldIndex( | ... | @@ -25773,8 +25761,8 @@ fn anonStructFieldIndex( |
| 25773 | return @intCast(u32, i); | 25761 | return @intCast(u32, i); |
| 25774 | } | 25762 | } |
| 25775 | } | 25763 | } |
| 25776 | return sema.fail(block, field_src, "anonymous struct '{}' has no such field '{s}'", .{ | 25764 | return sema.fail(block, field_src, "no field named '{s}' in anonymous struct '{}'", .{ |
| 25777 | struct_ty.fmt(sema.mod), field_name, | 25765 | field_name, struct_ty.fmt(sema.mod), |
| 25778 | }); | 25766 | }); |
| 25779 | } | 25767 | } |
| 25780 | | 25768 | |