| ... | ... | @@ -26629,21 +26629,41 @@ fn resolveStructLayout( |
| 26629 | 26629 | switch (struct_obj.status) { |
| 26630 | 26630 | .none, .have_field_types => {}, |
| 26631 | 26631 | .field_types_wip, .layout_wip => { |
| 26632 | | return sema.fail(block, src, "struct '{}' depends on itself", .{ty.fmt(sema.mod)}); |
| 26632 | const msg = try Module.ErrorMsg.create( |
| 26633 | sema.gpa, |
| 26634 | struct_obj.srcLoc(sema.mod), |
| 26635 | "struct '{}' depends on itself", |
| 26636 | .{ty.fmt(sema.mod)}, |
| 26637 | ); |
| 26638 | return sema.failWithOwnedErrorMsg(msg); |
| 26633 | 26639 | }, |
| 26634 | 26640 | .have_layout, .fully_resolved_wip, .fully_resolved => return, |
| 26635 | 26641 | } |
| 26636 | 26642 | struct_obj.status = .layout_wip; |
| 26637 | | for (struct_obj.fields.values()) |field| { |
| 26638 | | try sema.resolveTypeLayout(block, src, field.ty); |
| 26643 | for (struct_obj.fields.values()) |field, i| { |
| 26644 | sema.resolveTypeLayout(block, src, field.ty) catch |err| switch (err) { |
| 26645 | error.AnalysisFail => { |
| 26646 | const msg = sema.err orelse return err; |
| 26647 | try sema.addFieldErrNote(block, ty, i, msg, "while checking this field", .{}); |
| 26648 | return err; |
| 26649 | }, |
| 26650 | else => return err, |
| 26651 | }; |
| 26639 | 26652 | } |
| 26640 | 26653 | struct_obj.status = .have_layout; |
| 26641 | 26654 | |
| 26642 | 26655 | // In case of querying the ABI alignment of this struct, we will ask |
| 26643 | 26656 | // for hasRuntimeBits() of each field, so we need "requires comptime" |
| 26644 | 26657 | // to be known already before this function returns. |
| 26645 | | for (struct_obj.fields.values()) |field| { |
| 26646 | | _ = try sema.typeRequiresComptime(block, src, field.ty); |
| 26658 | for (struct_obj.fields.values()) |field, i| { |
| 26659 | _ = sema.typeRequiresComptime(block, src, field.ty) catch |err| switch (err) { |
| 26660 | error.AnalysisFail => { |
| 26661 | const msg = sema.err orelse return err; |
| 26662 | try sema.addFieldErrNote(block, ty, i, msg, "while checking this field", .{}); |
| 26663 | return err; |
| 26664 | }, |
| 26665 | else => return err, |
| 26666 | }; |
| 26647 | 26667 | } |
| 26648 | 26668 | } |
| 26649 | 26669 | // otherwise it's a tuple; no need to resolve anything |
| ... | ... | @@ -26660,13 +26680,26 @@ fn resolveUnionLayout( |
| 26660 | 26680 | switch (union_obj.status) { |
| 26661 | 26681 | .none, .have_field_types => {}, |
| 26662 | 26682 | .field_types_wip, .layout_wip => { |
| 26663 | | return sema.fail(block, src, "union '{}' depends on itself", .{ty.fmt(sema.mod)}); |
| 26683 | const msg = try Module.ErrorMsg.create( |
| 26684 | sema.gpa, |
| 26685 | union_obj.srcLoc(sema.mod), |
| 26686 | "union '{}' depends on itself", |
| 26687 | .{ty.fmt(sema.mod)}, |
| 26688 | ); |
| 26689 | return sema.failWithOwnedErrorMsg(msg); |
| 26664 | 26690 | }, |
| 26665 | 26691 | .have_layout, .fully_resolved_wip, .fully_resolved => return, |
| 26666 | 26692 | } |
| 26667 | 26693 | union_obj.status = .layout_wip; |
| 26668 | | for (union_obj.fields.values()) |field| { |
| 26669 | | try sema.resolveTypeLayout(block, src, field.ty); |
| 26694 | for (union_obj.fields.values()) |field, i| { |
| 26695 | sema.resolveTypeLayout(block, src, field.ty) catch |err| switch (err) { |
| 26696 | error.AnalysisFail => { |
| 26697 | const msg = sema.err orelse return err; |
| 26698 | try sema.addFieldErrNote(block, ty, i, msg, "while checking this field", .{}); |
| 26699 | return err; |
| 26700 | }, |
| 26701 | else => return err, |
| 26702 | }; |
| 26670 | 26703 | } |
| 26671 | 26704 | union_obj.status = .have_layout; |
| 26672 | 26705 | } |
| ... | ... | @@ -26794,12 +26827,12 @@ pub fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) |
| 26794 | 26827 | switch (ty.tag()) { |
| 26795 | 26828 | .@"struct" => { |
| 26796 | 26829 | const struct_obj = ty.castTag(.@"struct").?.data; |
| 26797 | | try sema.resolveTypeFieldsStruct(block, src, ty, struct_obj); |
| 26830 | try sema.resolveTypeFieldsStruct(ty, struct_obj); |
| 26798 | 26831 | return ty; |
| 26799 | 26832 | }, |
| 26800 | 26833 | .@"union", .union_safety_tagged, .union_tagged => { |
| 26801 | 26834 | const union_obj = ty.cast(Type.Payload.Union).?.data; |
| 26802 | | try sema.resolveTypeFieldsUnion(block, src, ty, union_obj); |
| 26835 | try sema.resolveTypeFieldsUnion(ty, union_obj); |
| 26803 | 26836 | return ty; |
| 26804 | 26837 | }, |
| 26805 | 26838 | .type_info => return sema.resolveBuiltinTypeFields(block, src, "Type"), |
| ... | ... | @@ -26820,15 +26853,19 @@ pub fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) |
| 26820 | 26853 | |
| 26821 | 26854 | fn resolveTypeFieldsStruct( |
| 26822 | 26855 | sema: *Sema, |
| 26823 | | block: *Block, |
| 26824 | | src: LazySrcLoc, |
| 26825 | 26856 | ty: Type, |
| 26826 | 26857 | struct_obj: *Module.Struct, |
| 26827 | 26858 | ) CompileError!void { |
| 26828 | 26859 | switch (struct_obj.status) { |
| 26829 | 26860 | .none => {}, |
| 26830 | 26861 | .field_types_wip => { |
| 26831 | | return sema.fail(block, src, "struct '{}' depends on itself", .{ty.fmt(sema.mod)}); |
| 26862 | const msg = try Module.ErrorMsg.create( |
| 26863 | sema.gpa, |
| 26864 | struct_obj.srcLoc(sema.mod), |
| 26865 | "struct '{}' depends on itself", |
| 26866 | .{ty.fmt(sema.mod)}, |
| 26867 | ); |
| 26868 | return sema.failWithOwnedErrorMsg(msg); |
| 26832 | 26869 | }, |
| 26833 | 26870 | .have_field_types, |
| 26834 | 26871 | .have_layout, |
| ... | ... | @@ -26842,17 +26879,17 @@ fn resolveTypeFieldsStruct( |
| 26842 | 26879 | try semaStructFields(sema.mod, struct_obj); |
| 26843 | 26880 | } |
| 26844 | 26881 | |
| 26845 | | fn resolveTypeFieldsUnion( |
| 26846 | | sema: *Sema, |
| 26847 | | block: *Block, |
| 26848 | | src: LazySrcLoc, |
| 26849 | | ty: Type, |
| 26850 | | union_obj: *Module.Union, |
| 26851 | | ) CompileError!void { |
| 26882 | fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_obj: *Module.Union) CompileError!void { |
| 26852 | 26883 | switch (union_obj.status) { |
| 26853 | 26884 | .none => {}, |
| 26854 | 26885 | .field_types_wip => { |
| 26855 | | return sema.fail(block, src, "union '{}' depends on itself", .{ty.fmt(sema.mod)}); |
| 26886 | const msg = try Module.ErrorMsg.create( |
| 26887 | sema.gpa, |
| 26888 | union_obj.srcLoc(sema.mod), |
| 26889 | "union '{}' depends on itself", |
| 26890 | .{ty.fmt(sema.mod)}, |
| 26891 | ); |
| 26892 | return sema.failWithOwnedErrorMsg(msg); |
| 26856 | 26893 | }, |
| 26857 | 26894 | .have_field_types, |
| 26858 | 26895 | .have_layout, |
| ... | ... | @@ -27786,9 +27823,19 @@ pub fn typeHasOnePossibleValue( |
| 27786 | 27823 | .@"struct" => { |
| 27787 | 27824 | const resolved_ty = try sema.resolveTypeFields(block, src, ty); |
| 27788 | 27825 | const s = resolved_ty.castTag(.@"struct").?.data; |
| 27789 | | for (s.fields.values()) |value| { |
| 27790 | | if (value.is_comptime) continue; |
| 27791 | | if ((try sema.typeHasOnePossibleValue(block, src, value.ty)) == null) { |
| 27826 | for (s.fields.values()) |field, i| { |
| 27827 | if (field.is_comptime) continue; |
| 27828 | if (field.ty.eql(resolved_ty, sema.mod)) { |
| 27829 | const msg = try Module.ErrorMsg.create( |
| 27830 | sema.gpa, |
| 27831 | s.srcLoc(sema.mod), |
| 27832 | "struct '{}' depends on itself", |
| 27833 | .{ty.fmt(sema.mod)}, |
| 27834 | ); |
| 27835 | try sema.addFieldErrNote(block, resolved_ty, i, msg, "while checking this field", .{}); |
| 27836 | return sema.failWithOwnedErrorMsg(msg); |
| 27837 | } |
| 27838 | if ((try sema.typeHasOnePossibleValue(block, src, field.ty)) == null) { |
| 27792 | 27839 | return null; |
| 27793 | 27840 | } |
| 27794 | 27841 | } |
| ... | ... | @@ -27854,6 +27901,16 @@ pub fn typeHasOnePossibleValue( |
| 27854 | 27901 | const tag_val = (try sema.typeHasOnePossibleValue(block, src, union_obj.tag_ty)) orelse |
| 27855 | 27902 | return null; |
| 27856 | 27903 | const only_field = union_obj.fields.values()[0]; |
| 27904 | if (only_field.ty.eql(resolved_ty, sema.mod)) { |
| 27905 | const msg = try Module.ErrorMsg.create( |
| 27906 | sema.gpa, |
| 27907 | union_obj.srcLoc(sema.mod), |
| 27908 | "union '{}' depends on itself", |
| 27909 | .{ty.fmt(sema.mod)}, |
| 27910 | ); |
| 27911 | try sema.addFieldErrNote(block, resolved_ty, 0, msg, "while checking this field", .{}); |
| 27912 | return sema.failWithOwnedErrorMsg(msg); |
| 27913 | } |
| 27857 | 27914 | const val_val = (try sema.typeHasOnePossibleValue(block, src, only_field.ty)) orelse |
| 27858 | 27915 | return null; |
| 27859 | 27916 | // TODO make this not allocate. The function in `Type.onePossibleValue` |
| ... | ... | @@ -28493,7 +28550,7 @@ pub fn typeRequiresComptime(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Typ |
| 28493 | 28550 | if (struct_obj.status == .field_types_wip) |
| 28494 | 28551 | return false; |
| 28495 | 28552 | |
| 28496 | | try sema.resolveTypeFieldsStruct(block, src, ty, struct_obj); |
| 28553 | try sema.resolveTypeFieldsStruct(ty, struct_obj); |
| 28497 | 28554 | |
| 28498 | 28555 | struct_obj.requires_comptime = .wip; |
| 28499 | 28556 | for (struct_obj.fields.values()) |field| { |
| ... | ... | @@ -28518,7 +28575,7 @@ pub fn typeRequiresComptime(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Typ |
| 28518 | 28575 | if (union_obj.status == .field_types_wip) |
| 28519 | 28576 | return false; |
| 28520 | 28577 | |
| 28521 | | try sema.resolveTypeFieldsUnion(block, src, ty, union_obj); |
| 28578 | try sema.resolveTypeFieldsUnion(ty, union_obj); |
| 28522 | 28579 | |
| 28523 | 28580 | union_obj.requires_comptime = .wip; |
| 28524 | 28581 | for (union_obj.fields.values()) |field| { |