| ... | @@ -9536,9 +9536,36 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE | ... | @@ -9536,9 +9536,36 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 9536 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; | 9536 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 9537 | const src = inst_data.src(); | 9537 | const src = inst_data.src(); |
| 9538 | const obj_ty = try sema.resolveType(block, src, inst_data.operand); | 9538 | const obj_ty = try sema.resolveType(block, src, inst_data.operand); |
| | 9539 | const gpa = sema.gpa; |
| 9539 | | 9540 | |
| 9540 | switch (obj_ty.zigTypeTag()) { | 9541 | switch (obj_ty.zigTypeTag()) { |
| 9541 | .Struct => return sema.addConstant(obj_ty, Value.initTag(.empty_struct_value)), | 9542 | .Struct => { |
| | 9543 | // This logic must be synchronized with that in `zirStructInit`. |
| | 9544 | const struct_ty = try sema.resolveTypeFields(block, src, obj_ty); |
| | 9545 | const struct_obj = struct_ty.castTag(.@"struct").?.data; |
| | 9546 | |
| | 9547 | // The init values to use for the struct instance. |
| | 9548 | const field_inits = try gpa.alloc(Air.Inst.Ref, struct_obj.fields.count()); |
| | 9549 | defer gpa.free(field_inits); |
| | 9550 | |
| | 9551 | var root_msg: ?*Module.ErrorMsg = null; |
| | 9552 | |
| | 9553 | for (struct_obj.fields.values()) |field, i| { |
| | 9554 | if (field.default_val.tag() == .unreachable_value) { |
| | 9555 | const field_name = struct_obj.fields.keys()[i]; |
| | 9556 | const template = "missing struct field: {s}"; |
| | 9557 | const args = .{field_name}; |
| | 9558 | if (root_msg) |msg| { |
| | 9559 | try sema.errNote(block, src, msg, template, args); |
| | 9560 | } else { |
| | 9561 | root_msg = try sema.errMsg(block, src, template, args); |
| | 9562 | } |
| | 9563 | } else { |
| | 9564 | field_inits[i] = try sema.addConstant(field.ty, field.default_val); |
| | 9565 | } |
| | 9566 | } |
| | 9567 | return sema.finishStructInit(block, src, field_inits, root_msg, struct_obj, struct_ty, false); |
| | 9568 | }, |
| 9542 | .Array => { | 9569 | .Array => { |
| 9543 | if (obj_ty.sentinel()) |sentinel| { | 9570 | if (obj_ty.sentinel()) |sentinel| { |
| 9544 | const val = try Value.Tag.empty_array_sentinel.create(sema.arena, sentinel); | 9571 | const val = try Value.Tag.empty_array_sentinel.create(sema.arena, sentinel); |
| ... | @@ -9572,6 +9599,7 @@ fn zirStructInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is_ref: bool) | ... | @@ -9572,6 +9599,7 @@ fn zirStructInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is_ref: bool) |
| 9572 | const resolved_ty = try sema.resolveTypeFields(block, src, unresolved_struct_type); | 9599 | const resolved_ty = try sema.resolveTypeFields(block, src, unresolved_struct_type); |
| 9573 | | 9600 | |
| 9574 | if (resolved_ty.castTag(.@"struct")) |struct_payload| { | 9601 | if (resolved_ty.castTag(.@"struct")) |struct_payload| { |
| | 9602 | // This logic must be synchronized with that in `zirStructInitEmpty`. |
| 9575 | const struct_obj = struct_payload.data; | 9603 | const struct_obj = struct_payload.data; |
| 9576 | | 9604 | |
| 9577 | // Maps field index to field_type index of where it was already initialized. | 9605 | // Maps field index to field_type index of where it was already initialized. |
| ... | @@ -9633,37 +9661,7 @@ fn zirStructInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is_ref: bool) | ... | @@ -9633,37 +9661,7 @@ fn zirStructInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is_ref: bool) |
| 9633 | field_inits[i] = try sema.addConstant(field.ty, field.default_val); | 9661 | field_inits[i] = try sema.addConstant(field.ty, field.default_val); |
| 9634 | } | 9662 | } |
| 9635 | } | 9663 | } |
| 9636 | if (root_msg) |msg| { | 9664 | return sema.finishStructInit(block, src, field_inits, root_msg, struct_obj, resolved_ty, is_ref); |
| 9637 | const fqn = try struct_obj.getFullyQualifiedName(gpa); | | |
| 9638 | defer gpa.free(fqn); | | |
| 9639 | try sema.mod.errNoteNonLazy( | | |
| 9640 | struct_obj.srcLoc(), | | |
| 9641 | msg, | | |
| 9642 | "struct '{s}' declared here", | | |
| 9643 | .{fqn}, | | |
| 9644 | ); | | |
| 9645 | return sema.failWithOwnedErrorMsg(msg); | | |
| 9646 | } | | |
| 9647 | | | |
| 9648 | if (is_ref) { | | |
| 9649 | return sema.fail(block, src, "TODO: Sema.zirStructInit is_ref=true", .{}); | | |
| 9650 | } | | |
| 9651 | | | |
| 9652 | const is_comptime = for (field_inits) |field_init| { | | |
| 9653 | if (!(try sema.isComptimeKnown(block, src, field_init))) { | | |
| 9654 | break false; | | |
| 9655 | } | | |
| 9656 | } else true; | | |
| 9657 | | | |
| 9658 | if (is_comptime) { | | |
| 9659 | const values = try sema.arena.alloc(Value, field_inits.len); | | |
| 9660 | for (field_inits) |field_init, i| { | | |
| 9661 | values[i] = (sema.resolveMaybeUndefVal(block, src, field_init) catch unreachable).?; | | |
| 9662 | } | | |
| 9663 | return sema.addConstant(resolved_ty, try Value.Tag.@"struct".create(sema.arena, values)); | | |
| 9664 | } | | |
| 9665 | | | |
| 9666 | return sema.fail(block, src, "TODO: Sema.zirStructInit for runtime-known struct values", .{}); | | |
| 9667 | } else if (resolved_ty.cast(Type.Payload.Union)) |union_payload| { | 9665 | } else if (resolved_ty.cast(Type.Payload.Union)) |union_payload| { |
| 9668 | const union_obj = union_payload.data; | 9666 | const union_obj = union_payload.data; |
| 9669 | | 9667 | |
| ... | @@ -9698,6 +9696,51 @@ fn zirStructInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is_ref: bool) | ... | @@ -9698,6 +9696,51 @@ fn zirStructInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is_ref: bool) |
| 9698 | unreachable; | 9696 | unreachable; |
| 9699 | } | 9697 | } |
| 9700 | | 9698 | |
| | 9699 | fn finishStructInit( |
| | 9700 | sema: *Sema, |
| | 9701 | block: *Block, |
| | 9702 | src: LazySrcLoc, |
| | 9703 | field_inits: []const Air.Inst.Ref, |
| | 9704 | root_msg: ?*Module.ErrorMsg, |
| | 9705 | struct_obj: *Module.Struct, |
| | 9706 | struct_ty: Type, |
| | 9707 | is_ref: bool, |
| | 9708 | ) !Air.Inst.Ref { |
| | 9709 | const gpa = sema.gpa; |
| | 9710 | |
| | 9711 | if (root_msg) |msg| { |
| | 9712 | const fqn = try struct_obj.getFullyQualifiedName(gpa); |
| | 9713 | defer gpa.free(fqn); |
| | 9714 | try sema.mod.errNoteNonLazy( |
| | 9715 | struct_obj.srcLoc(), |
| | 9716 | msg, |
| | 9717 | "struct '{s}' declared here", |
| | 9718 | .{fqn}, |
| | 9719 | ); |
| | 9720 | return sema.failWithOwnedErrorMsg(msg); |
| | 9721 | } |
| | 9722 | |
| | 9723 | if (is_ref) { |
| | 9724 | return sema.fail(block, src, "TODO: Sema.zirStructInit is_ref=true", .{}); |
| | 9725 | } |
| | 9726 | |
| | 9727 | const is_comptime = for (field_inits) |field_init| { |
| | 9728 | if (!(try sema.isComptimeKnown(block, src, field_init))) { |
| | 9729 | break false; |
| | 9730 | } |
| | 9731 | } else true; |
| | 9732 | |
| | 9733 | if (is_comptime) { |
| | 9734 | const values = try sema.arena.alloc(Value, field_inits.len); |
| | 9735 | for (field_inits) |field_init, i| { |
| | 9736 | values[i] = (sema.resolveMaybeUndefVal(block, src, field_init) catch unreachable).?; |
| | 9737 | } |
| | 9738 | return sema.addConstant(struct_ty, try Value.Tag.@"struct".create(sema.arena, values)); |
| | 9739 | } |
| | 9740 | |
| | 9741 | return sema.fail(block, src, "TODO: Sema.zirStructInit for runtime-known struct values", .{}); |
| | 9742 | } |
| | 9743 | |
| 9701 | fn zirStructInitAnon(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is_ref: bool) CompileError!Air.Inst.Ref { | 9744 | fn zirStructInitAnon(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is_ref: bool) CompileError!Air.Inst.Ref { |
| 9702 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 9745 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 9703 | const src = inst_data.src(); | 9746 | const src = inst_data.src(); |
| ... | @@ -14486,7 +14529,12 @@ fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) Comp | ... | @@ -14486,7 +14529,12 @@ fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) Comp |
| 14486 | | 14529 | |
| 14487 | struct_obj.status = .field_types_wip; | 14530 | struct_obj.status = .field_types_wip; |
| 14488 | try semaStructFields(sema.mod, struct_obj); | 14531 | try semaStructFields(sema.mod, struct_obj); |
| 14489 | struct_obj.status = .have_field_types; | 14532 | |
| | 14533 | if (struct_obj.fields.count() == 0) { |
| | 14534 | struct_obj.status = .have_layout; |
| | 14535 | } else { |
| | 14536 | struct_obj.status = .have_field_types; |
| | 14537 | } |
| 14490 | | 14538 | |
| 14491 | return ty; | 14539 | return ty; |
| 14492 | }, | 14540 | }, |